【问题标题】:How to properly interact with a process using subprocess module如何使用子流程模块与流程正确交互
【发布时间】:2010-10-01 09:06:39
【问题描述】:

我在使用 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

【问题讨论】:

标签: python subprocess


【解决方案1】:

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

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

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

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

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

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

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-08
  • 2019-04-01
相关资源
最近更新 更多