管道的问题在于,如果您调用读取操作并且没有任何内容可读取,则您的代码将陷入停滞,直到对方写入一些内容供您读取。此外,如果您写入太多,您的下一个写入操作可能会阻塞,直到另一方从管道中读取某些内容并释放它为止。
您可以进行“非阻塞调用”,在这些情况下将返回错误而不是阻塞,但您的应用程序仍然需要明智地处理错误。
无论如何,您需要设置某种protocol。想想 HTTP 或您熟悉的任何其他协议:有请求和响应,当您阅读这两个协议中的任何一个时,协议总是会告诉您是否还有其他内容需要阅读。这样您就可以随时就是否等待更多数据做出明智的决定。
这是一个有效的示例。它之所以有效,是因为有以下协议:
- p1 发送一行,以 '\n' 结尾;
- p2 也做同样的事情;
- p1 发送另一行;
- p2 也做同样的事情;
- 两人都很高兴并退出。
为了向管道(任一侧)写入一行并确保它进入管道,我调用write()
进而flush()
.
为了从管道(任一侧)读取一行,但不能再读取一个字节,从而阻塞我的代码,直到该行准备好且不超过该长度,我使用readline()
.
您还可以进行其他调用和其他协议,包括现成的协议,但单行协议非常适合简单的事情和像这样的演示。
p1.py:
import subprocess
p = subprocess.Popen(['python', 'p2.py'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
p.stdin.write("Hello\n")
p.stdin.flush()
print 'got', p.stdout.readline().strip()
p.stdin.write("How are you?\n")
p.stdin.flush()
print 'got', p.stdout.readline().strip()
p2.py:
import sys
data = sys.stdin.readline()
sys.stdout.write("Hm.\n")
sys.stdout.flush()
data = sys.stdin.readline()
sys.stdout.write("Whatever.\n")
sys.stdout.flush()