Python使用子进程与其他应用程序交谈

时间:2012-08-02 08:59:05

标签: python subprocess

这是个主意。我将有'main'python脚本将启动(使用子进程)app1和app2。 'main'脚本会将输入发送到app1并将结果输出到app2,反之亦然(主脚本需要记住发送的内容,因此我无法将管道从app1发送到app2)。

这是主要的脚本。

import subprocess
import time

def main():
    prvi = subprocess.Popen(['python', 'random1.py'], stdin = subprocess.PIPE , stdout = subprocess.PIPE, stderr = subprocess.STDOUT)

    while 1:
        prvi.stdin.write('131231\n')
        time.sleep(1) # maybe it needs to wait
        print "procitano", prvi.stdout.read()

if __name__ == '__main__':
    main()

这是'random1.py'文件。

import random

def main():
    while 1:
        inp = raw_input()
        print inp, random.random()
if __name__ == '__main__':
    main()

首先,我只尝试了一个子流程,看看它是否正常工作。事实并非如此。它只输出'procitano'并在那里等待。 如何从'prvi'读取输出(没有communication()。当我使用它时,它退出我的应用程序,这是我不想要的东西)?

3 个答案:

答案 0 :(得分:2)

prvi.stdin.flush()之后添加prvi.stdin.write(...)

说明:为了优化进程之间的通信,操作系统会在将整个缓冲区发送到另一个进程之前缓冲4KB的数据。如果您发送的数据较少,则需要告诉操作系统“就是这样。现在发送 ” - > flush()

[编辑] 下一个问题是prvi.stdout.read()永远不会返回,因为孩子没有退出。

您需要在进程之间开发协议,因此每个进程都知道要读取的数据字节数。一个简单的解决方案是使用基于行的协议(每个“消息”由新行终止)。为此,请将read()替换为readline(),并且不要忘记将\n附加到您发送的所有内容+ flush()

答案 1 :(得分:1)

<强> main.py

import subprocess
import time

def main():
    prvi = subprocess.Popen(['python', 'random1.py'], stdin = subprocess.PIPE , stdout = subprocess.PIPE, stderr = subprocess.STDOUT)


    prvi.stdin.write('131231\n')
    time.sleep(1) # maybe it needs to wait
    print "procitano", prvi.stdout.read()

if __name__ == '__main__':
    main()

<强> random1.py

import random

def main():

    inp = raw_input()
    print inp, random.random()
    inp = raw_input()

if __name__ == '__main__':
    main()

我已经使用上面的代码进行了测试,然后我遇到了与您的代码相同的问题。 我认为问题在于时机。 这是我的猜测, 当main.py尝试下面的代码时

prvi.stdout.read()  # i think this code may use the random1.py process

下面的代码抓住random1.py进程

inp = raw_input()

为了解决这个问题,我认为,正如Aaron Digulla所说,你需要开发协议来制作它。

答案 2 :(得分:1)

  • 使用-u标志使random1.py输出无缓冲
  • 使用p.stdout.readline()而不是.read()
由于.read块,

time.sleep是不必要的。