简体   繁体   English

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

[英]How to stream messages in a pipe from one process to another?

I have 2 python (2.7) processes. 我有2个python(2.7)进程。
The parent process needs to send rows of text to a child process, and the child process should process them as they come in (not wait for the parent process to finish). 父流程需要将文本行发送给子流程,子流程应在输入时处理它们(而不是等待父流程完成)。

I have this code which doesn't work: 我有此代码不起作用:

# 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()

And the child process: 和子进程:

# Receiver
import sys

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

The problem is that the child process waits until the parent process exits before it prints out the messages. 问题是子进程会等到父进程退出后才打印出消息。

What I'm trying to achieve is a child process that processes the messages as soon as they are written to the pipe. 我想要实现的是一个子进程,该子进程会在将消息写入管道后立即对其进行处理。

Try adding a process.stdin.flush() after your process.stdin.write() . 尝试在process.stdin.flush()之后添加process.stdin.write() That way you actually send the string to the other process. 这样,您实际上会将字符串发送给其他进程。 What you're suffering from here is your kernel caching everything you write. 您在这里遭受的是您的内核将您编写的所有内容都缓存。 It does this to be more efficient when actually sending the data to the other process. 实际将数据发送到其他进程时,这样做可以提高效率。 flush force the kernel to send your data regardless of how full the kernel's buffer is. 刷新将强制内核发送您的数据,而不管内核的缓冲区有多满。

I tried your code as such: 我尝试了这样的代码:

# 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()

With "works well" here i mean that i get "This is my message" printed as fast as the computer can perform. 这里的“效果很好”是指我以计算机可以执行的速度打印“这是我的消息”。 I'm trying this in Python 2.7.12 for the record. 我正尝试在Python 2.7.12中进行记录。

The story of how buffering works for sys.stdin and sys.stdout has made me cry more than once. 关于sys.stdinsys.stdout缓冲工作原理的故事使我不止一次哭泣。 A similar problem is discussed in Setting smaller buffer size for sys.stdin? 为sys.stdin设置较小的缓冲区大小中讨论了类似的问题 .

As to your specific problem, I suggest you change your child to use sys.stdin.readline() instead of iterating over sys.stdin . 关于您的特定问题,建议您更改孩子以使用sys.stdin.readline()而不是遍历sys.stdin The former somewhat "buffers less" :) 前者有些“缓冲较少” :)

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

In the parent, you'll likely either need to set bufsize=0 in your call to Popen (making your pipe completely unbuffered), or you'll need the process.stdin.flush() line, as Patrik suggests. 在父级中,您可能需要在对Popen的调用中设置bufsize=0 (使管道完全无缓冲),或者需要如Patrik建议的那样使用process.stdin.flush()行。 I'd opt for the latter. 我选择后者。

Tested on Python 2.7.14 on Windows 10 64bit. 已在Windows 10 64bit的Python 2.7.14上测试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在Python中停止一个进程 - how to stop one process from another in Python 如何将异常从一个进程传递到另一个进程? - How to pass exception from one process to another? 如何从一个过程向另一个过程发出信号? - How to signal from one process to another? python Discord Bot 如何将消息从一个通道发送到另一个通道 - python Discord Bot how to send messages from one channel to another 如何将视频 stream 从一个 python 传递到另一个? - How to pass video stream from one python to another? 如何使用 pipe 将一个进程传递给另一个进程(读取文件内容-获取内容-创建新文件)? - How can I pass one process to another using pipe (read file contents-get contents-create new file)? 如何使用python和pysftp从一个SFTP传输到另一个SFTP - How to stream from one SFTP to another SFTP using python and pysftp 如何将数据从一个模型字段处理到另一个模型字段 - How to process data from one model field to another 如何将print和stdout重定向到管道并从父进程读取它? - How to redirect print and stdout to a pipe and read it from parent process? 在 PYTHON 中将网格从一个进程转移到另一个进程 - Transferring a mesh from one process to another in PYTHON
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM