0

Using the following code, poll_obj.poll() blocks until sleep has completed:

import select, subprocess, time, fcntl, os

poll_obj = select.poll()
popen_obj = subprocess.Popen("sleep 5", stdout=subprocess.PIPE, stderr=subprocess.PIPE, 
                             close_fds=True, shell=True)
fcntl.fcntl(popen_obj.stdout, fcntl.F_SETFL, os.O_NONBLOCK)
fcntl.fcntl(popen_obj.stderr, fcntl.F_SETFL, os.O_NONBLOCK)
poll_obj.register(popen_obj.stdout)
poll_obj.register(popen_obj.stderr)
start_time = time.time()
poll_obj.poll()
print(time.time() - start_time)

It is my understanding that poll_obj.poll() shouldn't block because the O_NONBLOCK flag is set on the FDs it tracks. It should return None.

Is there a way to prevent poll_obj.poll() from blocking?

1 Answers1

0

poll_obj.poll() is supposed to block until there is something to read in a one of registered file descriptors. That blocking that you want to prevent is a desired feature. If that is not what you want, don't use poll.

Other commands probably either print something quickly (and poll does not have to wait for file descirptors to have something to read) or terminates quickly. The blocking time may be zero or close to zero, but poll follows the same logic as in sleep case.

sleep does not print anything and does not terminate quickly, so poll is blocked as expected.

EDIT

O_NONBLOCK that you used does not affect poll the way you expect. Use poll_obj.poll(0) to return from the call immediately even if there is nothing to read.

Community
  • 1
  • 1
Bartosz Marcinkowski
  • 6,651
  • 4
  • 39
  • 69
  • poll() doesn't normally block in the code I posted because the O_NONBLOCK flag is set on the FDs it tracks. You can try it with some other long running command and you'll see that poll() normally returns None. –  Feb 12 '15 at 11:29
  • Yeah, some way, but not the way you expect. `poll_obj.poll(0)` will do (I tried it), as I mentioned in edited answer. – Bartosz Marcinkowski Feb 12 '15 at 11:45