我在使用子进程模块重定向另一个程序的stdio时遇到问题。只是从stdout读取导致挂起,并且Popen.communicate()可以工作,但它在读/写后关闭管道。实现这个最简单的方法是什么?
我在Windows上玩这个:
import subprocess
proc = subprocess.Popen('python -c "while True: print \'Hi %s!\' % raw_input()"',
shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
while True:
proc.stdin.write('world\n')
proc_read = proc.stdout.readline()
if proc_read:
print proc_read
答案 0 :(得分:17)
不适合你的例子,但有助于理解潜在的问题:进程P启动子C.子C将一些内容写入其stdout。 C的stdout是一个具有4096个字符缓冲区且输出短于此的管道。现在,C等待一些输入。对于C,一切都很好。
P等待输出永远不会出现,因为操作系统没有理由刷新C的输出缓冲区(其中的数据太少)。因为P永远不会得到C的输出,所以它永远不会向C写入任何东西,所以C挂起等待来自P的输入。
修复:在每次写入管道后使用刷新,强制操作系统立即发送数据 。
在您的情况下,在主要的while循环中添加proc.stdin.flush()
,在打印后在子循环中添加sys.stdout.flush()
可以解决您的问题。
您还应该考虑将从其他进程读取的代码移动到一个线程中。这里的想法是你永远不知道数据何时到达,并且在编写处理结果的代码时使用线程可以帮助你理解这些问题。
在这个地方,我想向您展示新的Python 2.6文档,但它没有解释冲洗问题,或者:(好吧......)