如何将管道中的消息从一个进程流式传输到另一个进程?

时间:2018-02-11 12:55:55

标签: python python-2.7 multiprocessing

我有2个python(2.7)进程 父进程需要将文本行发送到子进程,子进程应该在进入时处理它们(不等待父进程完成)。

我有这个代码不起作用:

# Sender
import subprocess

process = subprocess.Popen(['python', 'child.py'], bufsize=1, stdin=subprocess.PIPE)

try:
    while True:
        process.stdin.write(msg + '\n')  # 'msg' is a changing string
        # process.stdin.flush() <-- commented out since it doesn't help
except KeyboardInterrupt:
    process.stdin.close()
    process.wait()

孩子过程:

# Receiver
import sys

for line in sys.stdin:
    print line.strip()

问题是子进程在打印出消息之前一直等到父进程退出。

我想要实现的是一个子进程,它会在将消息写入管道后立即对其进行处理。

2 个答案:

答案 0 :(得分:0)

尝试在process.stdin.flush()之后添加process.stdin.write()。这样你实际上将字符串发送到另一个进程。你在这里遇到的是你的内核缓存你写的一切。在将数据实际发送到其他进程时,这样做会更有效。 flush强制内核发送数据,无论内核的缓冲区有多满。

我尝试了你的代码:

# Sender
import subprocess                                                                                                                                                                                           

process = subprocess.Popen(['python', 'child.py'], bufsize=1, stdin=subprocess.PIPE)
msg = "This is my message"

try:
    while True:
        process.stdin.write(msg + '\n')  # 'msg' is a changing string
        process.stdin.flush() # This code works well for me regardless of the presence of this line
except KeyboardInterrupt:
    process.stdin.close()
    process.wait()

# Receiver
import sys

for line in sys.stdin:
    print line.strip()

在这里“运作良好”,我的意思是我得到“这是我的信息”,打印速度和电脑一样快。我正在Python 2.7.12中尝试这个记录。

答案 1 :(得分:0)

sys.stdinsys.stdout缓冲如何运作的故事让我不止一次哭泣。 Setting smaller buffer size for sys.stdin?中讨论了类似的问题。

至于您的具体问题,我建议您更改您的孩子使用sys.stdin.readline()而不是迭代sys.stdin。前者有点“减少缓冲”:)

while True:
    line = sys.stdin.readline()
    if not line: break
    print (line.strip())

在家长中,您可能需要在调用bufsize=0时设置Popen(使管道完全无缓冲),或者您需要process.stdin.flush()行,正如帕特里克所说。我会选择后者。

在Windows 10 64bit上测试Python 2.7.14。