通过管道让Python程序“聊天”

1 投票
4 回答
543 浏览
提问于 2025-04-16 01:25

我正在尝试让两个进程通过管道进行通信。

在父进程中,我做了如下操作:

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.readlinesys.stdout.write,这只是个人风格的选择。

我写了两个测试程序,它们在Fedora 13上使用python-2.6.4-27运行得很好。

撰写回答