与子进程通信,无需等待子进程在 windows 上终止

Posted

技术标签:

【中文标题】与子进程通信,无需等待子进程在 windows 上终止【英文标题】:Communicate with subprocess without waiting for the subprocess to terminate on windows 【发布时间】:2013-05-11 16:02:42 【问题描述】:

我有一个简单的 echoprocess.py:

import sys

while True:
    data = sys.stdin.read()
    sys.stdout.write("Here is the data: " + str(data))

还有一个 parentprocess.py

from subprocess import Popen, PIPE

proc = Popen(["C:/python27/python.exe", "echoprocess.py"],
             stdin = PIPE,
             sdtout = PIPE)

proc.stdin.write("hello")
print proc.stdout.read()

这只是挂起,直到 echoprocess.py 终止。我想多次与这个子进程通信,而不必再次重新启动它。 Windows 上的 Python 子进程模块可以实现这种进程间通信吗?

【问题讨论】:

刚刚在我的回答中添加了关于输出缓冲的注释。不确定 Windows,但在 Linux 上 echoprocess.py 中的那个是必要的,尽管 parentprocess.py 中的那个不是。始终包含它们以实现最大的便携性通常是最安全的。 可能还值得看看multiprocessing 模块,它为这种进程间通信提供了一个抽象层。 这就是我最初所做的,但我在 Windows 上遇到了一些初始问题。 Windows 要求将所有代码放在 if __name__ == "__main__": 块中似乎需要我已经拥有的太多工作。 【参考方案1】:

主要问题在于线路...

print proc.stdout.read()

read() 方法在不带参数使用时将读取所有数据,直到 EOF,直到子进程终止才会发生。

您可能会接受逐行阅读,因此您可以使用...

proc.stdin.write("hello\n")
print proc.stdout.readline()

...否则您将不得不想出一些其他方法来分隔“消息”。

您必须对echoprocess.py 进行类似的更改,即更改...

data = sys.stdin.read()

...到...

data = sys.stdin.readline()

您可能还会遇到输出缓冲问题,因此可能需要在写入后flush() 缓冲区。


如果您将echoprocess.py 更改为...

import sys

while True:
    data = sys.stdin.readline()
    sys.stdout.write("Here is the data: " + str(data))
    sys.stdout.flush()

...和parentprocess.py 到...

from subprocess import Popen, PIPE

proc = Popen(["C:/python27/python.exe", "echoprocess.py"],
             stdin = PIPE,
             stdout = PIPE)

proc.stdin.write("hello\n")
proc.stdin.flush()
print proc.stdout.readline()

...它应该按照您期望的方式工作。

【讨论】:

按预期工作。冲洗究竟是做什么的? @MichaelDavidWatson 好吧,为了提高效率,进程通常会有一个内部缓冲区,并且对 write() 的调用实际上将存储在缓冲区中,直到达到一定大小,此时它将被传递进入管道过程。调用flush() 会立即强制执行此操作,而不是等待缓冲区被填满。网络上的某个地方可能有更好的描述。

以上是关于与子进程通信,无需等待子进程在 windows 上终止的主要内容,如果未能解决你的问题,请参考以下文章

需要与子进程通信来处理文件

如何加快与子进程的通信

使用 stdout/stderr 以外的管道与子进程通信

shell向子进程发送信号

使用重定向 I/O 与子进程通信时出现死锁

我可以以某种方式与子进程共享一个异步队列吗?