Python,试图从子进程获取输入?

时间:2012-06-12 21:50:51

标签: python multiprocessing subprocess

main.py

import subprocess,sys
process = subprocess.Popen([sys.executable]+['example.py'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

while True:
    out = process.stdout.read(1)
    if not out:
        out=process.stderr.read(1)
    if out == '' and process.poll() != None:
        break
    if out != '':
        print out

example.py

f=raw_input('WHats your favorite animal')

好的,我想知道如何检查主循环中的输入并能够为其提供一些数据。现在,当我使用raw_input时,我的程序会冻结。

这是我想要的

while True:
    out = process.stdout.read(1)
    if not out:
        out=process.stderr.read(1)
    if out == '' and process.poll() != None:
        break
    #showing what i want
    if request_input==True:
        give_input('cat') #Give input to the raw_input
    #
    if out != '':
        print out

我不知道是否有这样的功能。如果您需要更多解释,请发表评论。

4 个答案:

答案 0 :(得分:4)

这实际上并不是进行进程间通信的最佳方式,我建议您使用多处理或线程库,使用Queue或PIPE进行通信和同步。

队列是共享数据的最简单方法,一个进程会放入一个值,另一个进程会得到值。

我已修改原始代码,因此它现在可以正常工作,请注意raw_input不会刷新stdout,如果它没有任何内容会挂起,http://code.activestate.com/lists/python-list/265749/这就是为什么你的代码只是在等待stdout ..

这是危险的,它会产生死锁,使用风险自负,尝试另一种方法。

import sys
print 'Whats your favorite animal\n' #raw_input doesn't flush :( and we want to read in a whole line
sys.stdout.flush()
f = raw_input()
print f

和相应的main.py

import subprocess, sys, os
process = subprocess.Popen([sys.executable]+['example.py'],
     stdout = subprocess.PIPE, stderr = subprocess.PIPE, stdin = subprocess.PIPE)

while True:
    if process.poll() != None:
        break
    request_input = process.stdout.readline() # read line, this will wait until there's actually a line to read.
    if request_input == "Whats your favorite animal\n":
        print 'request: %s sending: %s' % (request_input, 'cat')
        process.stdin.write('cat\n')
       process.stdin.flush()

答案 1 :(得分:1)

编辑:好像我很想理解你的问题,对不起。

这并不像你想象的那么容易:

您必须使用select检查stdin中是否有可用数据,如果有数据,请阅读!

最小例子:

STDIN, STDOUT = 0, 1

while not process.poll() is None:
    out = process.stdout.read(1)

    if not out:
        break

    try:
        fds = select.select([STDIN], [], [])[0]
    except select.error:
        pass
    else:
        if STDIN in fds:
            data = os.read(STDIN, 1024)

            if data_requested:
                process.stdin.write(data)

要选择的信息:http://docs.python.org/library/select.html#module-selecthttp://linux.die.net/man/2/selecthttp://en.wikipedia.org/wiki/Select_(Unix)

不确定这是否适用于Windows,因为Windows只支持套接字上的select。关于SO的相关问题:What is the best epoll/kqueue/select equvalient on Windows?

答案 2 :(得分:0)

尝试使用多处理模块

from multiprocessing import Process, Value, Array

def f(n, a):
    n.value = 3.1415927
    for i in range(len(a)):
        a[i] = -a[i]

if __name__ == '__main__':
    num = Value('d', 0.0)
    arr = Array('i', range(10))

    p = Process(target=f, args=(num, arr))
    p.start()
    p.join()

    print num.value
    print arr[:]

答案 3 :(得分:0)

除非你坚持“原始python”,否则最好是使用pexpect模块。我已经为你的example.py添加了一个输出,否则它根本就不好玩。

这是example.py:

    f=raw_input('WHats your favorite animal')
    print f.upper()

您正在寻找的是pexpect-example.py:

    # see http://pexpect.sourceforge.net/pexpect.html
    import pexpect

    PY_SCRIPT = 'example.py'

    child = pexpect.spawn('python %s' % PY_SCRIPT)

    child.expect ('WHats your favorite animal')

    # comment out these three lines if you run unmodified example.py script
    child.setecho(False)
    child.sendline ('cat')
    print PY_SCRIPT, 'said:', child.readline()