通过管道让Python程序“聊天”
我正在尝试让两个进程通过管道进行通信。
在父进程中,我做了如下操作:
process = subprocess.Popen(test, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
process.stdin.write("4\n");
output = process.stdout.read()
print output
而在子进程中,我做了这样的事情:
inp = raw_input()
integer = int(inp)
print integer**2
while(True):
pass
我本以为父进程会打印出16……可惜的是,它一直卡在那里,没有打印任何东西。如果把无限循环换成让它睡5秒钟,父进程就会闲着5秒,之后才打印出16。这说明父进程只有在子进程结束后才能得到输出。
我想知道是否可以在程序结束之前就获取输入。我的想法是通过这个管道不断传递信息,获取输入,处理它,然后把结果输出到管道中,这样另一个进程就可以继续处理。
有没有人能帮帮我?
谢谢,
曼努埃尔
4 个回答
0
你需要使用选择(select)这个方法。就像在子进程的沟通方法里那样。关于这个问题,在Python的错误追踪系统里有讨论。
4
我看到几个可能的问题:
a) 子进程可能根本没有把它的输出发送出去,也就是说它没有把数据“冲刷”到父进程。
b) 父进程在子进程还没发送输出(还没“冲刷”输出)之前就开始执行它的 read()
调用了。
c) 父进程在执行 read()
时是阻塞的,这意味着它会一直等到子进程结束才会继续。subprocess.Popen
的文档应该会提到这种情况。
d) 父进程的 read()
调用需要等到一定数量的字节(比如1024字节)到达后才会返回。
可能让父进程多次调用 read(1)
,然后把接收到的字节重新组合起来,就能解决这个问题。或者使用更高级的通信方式,比如用数据报而不是解析字节流。
2
正如ndim所建议的,在父进程中做以下操作:
process.stdin.write("4\n")
process.stdin.flush()
output = process.stdout.readline()
print output
你还需要修改子进程:
inp = sys.stdin.readline()
integer = int(inp)
sys.stdout.write("%d\n", (integer ** 2,))
sys.stdout.flush()
我使用了sys.stdin.readline
和sys.stdout.write
,这只是个人风格的选择。
我写了两个测试程序,它们在Fedora 13上使用python-2.6.4-27运行得很好。