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

Python 与子进程通信,无需等待子进程在windows上终止,python,subprocess,stdout,stdin,readline,Python,Subprocess,Stdout,Stdin,Readline,我有一个简单的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"],

我有一个简单的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子进程模块进行这种进程间通信?

主要问题在于

print proc.stdout.read()
read()
方法在没有参数的情况下使用时,将在EOF之前读取所有数据,而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()
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()
…和
parentprocess.py

import sys

while True:
    data = sys.stdin.readline()
    sys.stdout.write("Here is the data: " + str(data))
    sys.stdout.flush()
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()

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

刚刚在我的答案中添加了一个关于输出缓冲的注释。不确定Windows,但在Linux上,
echoprocess.py
中的一个是必需的,尽管
parentprocess.py
中的一个不是必需的。通常最安全的做法是始终包含它们以实现最大的可移植性。可能还值得一看模块,它为这种进程间通信提供了一个抽象层。这是我最初做的,但我在Windows上遇到了一些初始问题。Windows要求将所有代码放入
if\uuuuuu name\uuuuu==“\uuuuu main\uuuuu”:
块中,这似乎需要对我已有的代码进行太多的处理。工作正常。flush到底做什么?@MichaelDavidWatson为了提高效率,进程通常会有一个内部缓冲区,对
write()
的调用实际上会存储在缓冲区中,直到它达到一定的大小,在这一点上它会传递给管道化进程。调用
flush()。网络上可能有更好的描述。