如何使用子进程模块与进程正确交互

时间:2009-01-14 14:07:12

标签: python subprocess

我在使用子进程模块重定向另一个程序的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

1 个答案:

答案 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文档,但它没有解释冲洗问题,或者:(好吧......)