/usr/bin/sleep 导致轮询对象阻塞

/usr/bin/sleep causes poll object to block

使用以下代码,poll_obj.poll() 阻塞直到睡眠完成:

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)

据我了解,poll_obj.poll() 不应阻止,因为 O_NONBLOCK 标志设置在它跟踪的 FD 上。它应该 return None.

有没有办法防止poll_obj.poll()阻塞?

poll_obj.poll() 应该阻塞,直到在一个已注册的文件描述符中有可读取的内容。您想要阻止的阻塞是一个理想的特性。如果这不是您想要的,请不要使用 poll.

其他命令可能会快速打印某些内容(并且轮询不必等待文件描述符有内容可读)或快速终止。阻塞时间可能为零或接近于零,但 poll 遵循与 sleep 情况相同的逻辑。

sleep 不打印任何内容并且不会快速终止,因此轮询按预期被阻止。

编辑

O_NONBLOCK 你用过 does not affect poll the way you expect。使用 poll_obj.poll(0) 到 return 从调用立即即使没有什么可读的。