select.select example?
marco at atmosp.physics.utoronto.ca
marco at atmosp.physics.utoronto.ca
Tue Feb 20 20:46:09 EST 2001
Hi all,
A few days ago I posted a little problem I had regarding
the blocking of UNIX pipes. Basically, when I ran:
(po, pi, pe) = popen2.popen3('some command')
and then:
po_out = po.read()
pe_err = pe.read()
it happened sometimes (in an upredictable manner) that
po.read() got stuck and my program stopped on its tracks
(the order in which I read po and pe does make a difference,
but while reading po.read() first works 99% of the time,
I execute this many times and that 1% kills me).
Two suggestions came up. One was using fcntl which seems to
work, e.g.:
>>> import popen2, fcntl, FCNTL
>>> (po, pi, pe) = popen2.popen3('some command')
>>>
>>> # set read pipe to NONBLOCK, so we won't block
>>> # on read() when there aren't any data available at the time
>>>
>>> fcntl.fcntl(po.fileno(), FCNTL.F_SETFL, FCNTL.O_NONBLOCK)
>>> fcntl.fcntl(pe.fileno(), FCNTL.F_SETFL, FCNTL.O_NONBLOCK)
>>>
>>> # for child -- close above opened file descriptors on exec()
>>> fcntl.fcntl(pi.fileno(), FCNTL.F_SETFD, 1)
>>> fcntl.fcntl(po.fileno(), FCNTL.F_SETFD, 1)
>>> fcntl.fcntl(pe.fileno(), FCNTL.F_SETFD, 1)
>>>
>>> pout = po.read()
>>> perr = pe.read()
The other option was using the select module. If I understand correctly,
select.select will retrieve the input, output and error (exceptional
condition?) without me having to worry which to read first. If none
is available a timeout can also be specified. If this is the case
it's probably what I want, but unfortunately the documentation is
very scarce. From what I can gather:
>>> import popen2, select
>>> (po, pi, pe) = popen2.popen3('some command')
>>> (spo, spi, spe) = select.select([po], [pi], [pe], 10)
>>> spo[0].read()
seems to work, although according to the Python 1.5.2 Library
Reference the order of the lists should be:
select.select(input, output, error, 10)
which doesn't seem to be working for me. Furthermore, if
'some command' worked OK I would expect spe[0].read() to
be '' but instead I get the error:
IOError: [Errno 9] Bad file descriptor
On the other hand, when 'some command' *does* raise an error, then
spo[0].read() gives me '' (which is expected), but spe[0].read()
gives the error:
IndexError: list index out of range
instead of std_err.
So, I'm confused...
If anyone can provide me with a simple example using select.select
on a UNIX pipe I would greatly appreciate it! (And, of course, any
other solutions are greatly welcomed :)
Cheers!
----- Posted via NewsOne.Net: Free (anonymous) Usenet News via the Web -----
http://newsone.net/ -- Free reading and anonymous posting to 60,000+ groups
NewsOne.Net prohibits users from posting spam. If this or other posts
made through NewsOne.Net violate posting guidelines, email abuse at newsone.net
More information about the Python-list
mailing list