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