Python:如何查看 pty 对象以避免阻塞?
我正在使用 pty 读取非阻塞进程的标准输出,如下所示:
import os
import pty
import subprocess
master, slave = pty.openpty()
p = subprocess.Popen(cmd, stdout = slave)
stdout = os.fdopen(master)
while True:
if p.poll() != None:
break
print stdout.readline()
stdout.close()
除了 while-loop 偶尔阻塞之外,一切正常。这是因为 print stdout.readline()
行正在等待从 stdout
读取内容。但如果程序已经终止,我的小脚本将永远挂起。
我的问题是:有没有办法查看 stdout 对象并检查是否有数据可供读取?如果不是这种情况,它应该继续执行 while-loop
,在那里它会发现进程实际上已经终止并中断循环。
I am using pty
to read non blocking the stdout of a process like this:
import os
import pty
import subprocess
master, slave = pty.openpty()
p = subprocess.Popen(cmd, stdout = slave)
stdout = os.fdopen(master)
while True:
if p.poll() != None:
break
print stdout.readline()
stdout.close()
Everything works fine except that the while-loop
occasionally blocks. This is due to the fact that the line print stdout.readline()
is waiting for something to be read from stdout
. But if the program already terminated, my little script up there will hang forever.
My question is: Is there a way to peek into the stdout
object and check if there is data available to be read? If this is not the case it should continue through the while-loop
where it will discover that the process actually already terminated and break the loop.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,使用 select 模块的 poll:
并同时使用:
Yes, use the select module's poll:
and in the while use:
select.poll() 答案非常简洁,但在 Windows 上不起作用。以下解决方案是一种替代方案。它不允许您查看标准输出,但提供了 readline() 的非阻塞替代方案,并且基于此答案:
此处提出了其他非阻塞读取解决方案,但对我不起作用:
The select.poll() answer is very neat, but doesn't work on Windows. The following solution is an alternative. It doesn't allow you to peek stdout, but provides a non-blocking alternative to readline() and is based on this answer:
Other solutions for non-blocking read have been proposed here, but did not work for me: