Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用标准输入和标准输出在两个进程之间通信_Python_Subprocess - Fatal编程技术网

Python 使用标准输入和标准输出在两个进程之间通信

Python 使用标准输入和标准输出在两个进程之间通信,python,subprocess,Python,Subprocess,我想写一个简单的脚本(a),它执行一个外部脚本(B) A应该通过写入其标准输入和读取其标准输出来与B通信 B应阅读其标准数据并打印 所有这些都应该在不关闭流的情况下完成 A.py import subprocess process = subprocess.Popen(['python', 'B.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) for _ in range(3): process.stdin.write(b'h

我想写一个简单的脚本(a),它执行一个外部脚本(B)

  • A应该通过写入其标准输入和读取其标准输出来与B通信
  • B应阅读其标准数据并打印
所有这些都应该在不关闭流的情况下完成

A.py

import subprocess
process = subprocess.Popen(['python', 'B.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
for _ in range(3):
    process.stdin.write(b'hello')
    print(process.stdout.read())
import sys

for line in sys.stdin:
    print(line)
B.py

import subprocess
process = subprocess.Popen(['python', 'B.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
for _ in range(3):
    process.stdin.write(b'hello')
    print(process.stdout.read())
import sys

for line in sys.stdin:
    print(line)
输出应为:

>>> b'hello'
>>> b'hello'
>>> b'hello'
问题是A只是在等待

print(process.stdout.read())
如果我修改了,请添加close():

我得到:

>>> b'hello\n'
>>> Traceback (most recent call last):
>>>   File "A.py", line 7, in <module>
>>>     process.stdin.write(b'hello')
>>> ValueError: write to closed file
>>b'hello\n'
>>>回溯(最近一次呼叫最后一次):
>>>文件“A.py”,第7行,在
>>>process.stdin.write(b'hello')
>>>ValueError:写入已关闭的文件
使用 Python已经实现了方法(它转到
A.py
B.py
)。但是,如果您需要更复杂的数据,它只适用于简单的通信(您知道您要提前发送什么数据),如:

send data to process B
read stdout
if stdout ...
    do something bases on stdout
    write to stdin
您必须实现自己的
communicate()
,原始实现


一步一步地 我已经一步一步地测试和调试了这一点,下面是发生的情况:

# For Popen(bufsize!=0)
A: process.stdin.write(b'hello\r\n')
B: line = sys.stdin.readline() # Hangs
因此,在添加
bufsize=0
(无缓冲)后

那么什么有效呢

# Popen(bufsize=0)
A: process.stdin.write(b'hello\r\n')
B: line = sys.stdin.readline()
B: print('Send back', line.strip())
B: sys.stdout.flush()
A: process.stdout.readline()

解释 缓冲设置为(通常为4090B)。发件人:

当创建stdin/stdout/stderr管道文件对象时,bufsize将作为io.open()函数的相应参数提供:0表示未缓冲(读和写是一个系统调用,可以短返回),1表示行缓冲,任何其他正值表示使用大约该大小的缓冲。负bufsize(默认值)表示将使用系统默认的io.default\U BUFFER\U SIZE

因此,一开始
A
不会刷新,因为它还没有填满缓冲区,因此
B
正在等待。它在Windows下,因此您必须使用
bufsize=0

由于
readline()
,写也很重要

注意:我认为它应该也适用于
bufsize=1
(行缓冲),但它没有。我不知道为什么

然后在
B
中也会发生同样的情况,当它不会刷新
sys.stdout
时,
B:sys.stdout
没有设置为无缓冲,这让我感到惊讶,因为:

创建stdin/stdout/stderr管道文件对象时,bufsize将作为io.open()函数的相应参数提供

无论如何,您必须在
B
中调用
sys.stdout.flush()

它与
close()
一起工作,因为它强制
flush()


给我密码 A.py

import subprocess
import sys

process = subprocess.Popen([sys.executable, r'B.py'], stdin=subprocess.PIPE, 
                            stdout=subprocess.PIPE, bufsize=0)
for _ in range(3):
    process.stdin.write(b'hello\r\n')
    print(process.stdout.readline())
import sys

for line in sys.stdin:
    print('Send back', line.strip())
    sys.stdout.flush()
B.py

import subprocess
import sys

process = subprocess.Popen([sys.executable, r'B.py'], stdin=subprocess.PIPE, 
                            stdout=subprocess.PIPE, bufsize=0)
for _ in range(3):
    process.stdin.write(b'hello\r\n')
    print(process.stdout.readline())
import sys

for line in sys.stdin:
    print('Send back', line.strip())
    sys.stdout.flush()

添加后,它仍像尝试添加前一样等待\r\n,未成功。当添加刷新时,我在第二次迭代中遇到了这个错误:IOError:[Errno 22]无效的Argument哇,回答很好,对我来说也很有用,只是做了一点小小的更改,我在a中写入后刷新,而在B中根本没有刷新。我使用的是Python3.2,这会有什么不同吗?@OferHelman我在win32上运行的是Python3.2.5(默认,2013年5月15日,23:07:10)[MSC v.1500 64位(AMD64)]我想它可能是版本特定的。我发现让这些东西正常工作是一种魔力。有趣的是,与我的设置非常相似,我在你的答案中添加了适合我的排列