如何使用子流程模块与流程正确交互 [英] How to properly interact with a process using subprocess module

查看:31
本文介绍了如何使用子流程模块与流程正确交互的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在使用子进程模块重定向另一个程序的 stdio 时遇到问题.仅从 stdout 读取会导致挂起,并且 Popen.communicate() 工作但在读取/写入后关闭管道.实现此目标的最简单方法是什么?

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?

我在 Windows 上玩这个:

I was playing around with this on 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

推荐答案

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

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.

P 等待永远不会出现的输出,因为操作系统认为没有理由刷新 C 的输出缓冲区(其中的数据很少).由于 P 永远不会得到 C 的输出,它永远不会向 C 写任何东西,所以 C 挂起等待 P 的输入.

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.

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

Fix: Use flush after every write to a pipe forcing the OS to send the data now.

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

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.

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

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.

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

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 ...

这篇关于如何使用子流程模块与流程正确交互的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆