python 如何使用子流程模块与流程正确交互
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/443057/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to properly interact with a process using subprocess module
提问by Ivan Baldin
I'm having problems redirecting stdio of another program using subprocess module. Just reading from stdout results in hanging, and Popen.communicate() works but it closes pipes after reading/writing. What's the easiest way to implement this?
我在使用子进程模块重定向另一个程序的 stdio 时遇到问题。仅从 stdout 读取会导致挂起,并且 Popen.communicate() 工作但在读取/写入后关闭管道。实现这一点的最简单方法是什么?
I was playing around with this on windows:
我在 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
回答by Aaron Digulla
Doesn't fit 100% to your example but helps to understand the underlying issue: Process P starts child C. Child C writes something to its stdout. stdout of C is a pipe which has a 4096 character buffer and the output is shorter than that. Now, C waits for some input. For C, everything is fine.
不适合您的示例 100%,但有助于理解潜在问题:进程 P 启动子 C。子 C 向其标准输出写入一些内容。C 的标准输出是一个管道,它有一个 4096 个字符的缓冲区,输出比那个短。现在,C 等待一些输入。对于 C,一切都很好。
P waits for the output which will never come because the OS sees no reason to flush the output buffer of C (with so little data in it). Since P never gets the output of C, it will never write anything to C, so C hangs waiting for the input from P.
P 等待永远不会出现的输出,因为操作系统认为没有理由刷新 C 的输出缓冲区(其中的数据很少)。由于 P 永远不会得到 C 的输出,它永远不会向 C 写入任何内容,因此 C 挂起等待来自 P 的输入。
Fix: Use flush after every write to a pipe forcing the OS to send the data now.
修复:每写一个管道迫使OS发送数据后刷新使用现在。
In your case, adding proc.stdin.flush()
in the main while loop and a sys.stdout.flush()
in the child loop after the print should fix your problem.
在您的情况下,proc.stdin.flush()
在sys.stdout.flush()
打印后添加主 while 循环和子循环应该可以解决您的问题。
You should also consider moving the code which reads from the other process into a thread. The idea here is that you can never know when the data will arrive and using a thread helps you to understand these issues while you write the code which processes the results.
您还应该考虑将从其他进程读取的代码移动到线程中。这里的想法是,您永远无法知道数据何时到达,使用线程可以帮助您在编写处理结果的代码时理解这些问题。
At this place, I wanted to show you the new Python 2.6 documentation but it doesn't explain the flush issue, either :( Oh well ...
在这里,我想向您展示新的 Python 2.6 文档,但它也没有解释刷新问题:( 哦,好吧...