12

我在使用 subprocess 模块重定向另一个程序的 stdio 时遇到问题。仅从标准输出读取会导致挂起,并且 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
4

1 回答 1

20

不适合您的示例 100%,但有助于理解潜在问题:进程 P 启动子 C。子 C 将某些内容写入其标准输出。C 的 stdout 是一个具有 4096 字符缓冲区的管道,并且输出比这短。现在,C 等待一些输入。对于 C,一切都很好。

P 等待永远不会出现的输出,因为操作系统认为没有理由刷新 C 的输出缓冲区(其中的数据太少)。由于 P 永远不会得到 C 的输出,它永远不会向 C 写入任何内容,因此 C 挂起等待来自 P 的输入。

修复:每次写入管道后使用刷新,强制操作系统现在发送数据。

在您的情况下,在打印后添加proc.stdin.flush()主 while 循环和子循环中的 a 应该可以解决您的问题。sys.stdout.flush()

您还应该考虑将从其他进程读取的代码移动到线程中。这里的想法是,您永远无法知道数据何时到达,而使用线程可以帮助您在编写处理结果的代码时理解这些问题。

在这个地方,我想向您展示新的 Python 2.6 文档,但它也没有解释刷新问题 :( 哦,好吧...

于 2009-01-14T14:16:38.607 回答