Python在子进程中使用STDIN

时间:2011-09-20 18:29:24

标签: python process stdin

所以我有一个程序,在“主”过程中,我触发一个新的Process对象(我想要的)是从STDIN读取行并将它们附加到Queue对象。

基本上,基本的系统设置是有一个“命令获取”过程,用户将输入命令/查询,我需要将这些查询提供给在不同进程中运行的其他子系统。我的想法是通过多处理队列来共享这些,其他系统可以从中读取。

我所拥有的(专注于获取命令/查询)基本上是:

def sub_proc(q):
    some_str = ""
    while True:
        some_str = raw_input("> ")
        if some_str.lower() == "quit":
            return
        q.put_nowait(some_str)

if __name__ == "__main__":
    q = Queue()
    qproc = Process(target=sub_proc, args=(q,))
    qproc.start()
    qproc.join()

    # now at this point q should contain all the strings entered by the user

问题是我得到了:

Process Process-1:
Traceback (most recent call last):
  File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
    self.run()
  File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
    self._target(*self._args, **self._kwargs)
  File "/home/blah/blah/blah/blah.py", line 325, in sub_proc
    some_str = raw_input("> ")
  File "/randompathhere/eclipse/plugins/org.python.pydev_2.1.0.2011052613/PySrc/pydev_sitecustomize/sitecustomize.py", line 181, in raw_input
    ret = original_raw_input(prompt)
EOFError: EOF when reading a line

怎么办?

4 个答案:

答案 0 :(得分:8)

我通过将原始stdin文件描述符传递给子进程并在那里重新打开它来解决了类似的问题。

def sub_proc(q,fileno):
    sys.stdin = os.fdopen(fileno)  #open stdin in this process
    some_str = ""
    while True:
        some_str = raw_input("> ")

        if some_str.lower() == "quit":
            return
        q.put_nowait(some_str)

if __name__ == "__main__":
    q = Queue()
    fn = sys.stdin.fileno() #get original file descriptor
    qproc = Process(target=sub_proc, args=(q,fn))
    qproc.start()
    qproc.join()

这适用于我相对简单的案例。我甚至可以在重新打开的流上使用readline模块。我不知道它对于更复杂的系统有多强大。

答案 1 :(得分:3)

简而言之,主进程和第二个进程不共享相同的STDIN。

from multiprocessing import Process, Queue
import sys

def sub_proc():
    print sys.stdin.fileno()

if __name__ == "__main__":
    print sys.stdin.fileno()
    qproc = Process(target=sub_proc)
    qproc.start()
    qproc.join()

运行它,你应该得到两个不同的结果sys.stdin.fileno()

不幸的是,这并不能解决您的问题。你想做什么?

答案 2 :(得分:1)

如果你不想将stdin传递给目标进程函数,比如在@Ashelly的答案中,或者只是需要为许多不同的进程执行它,你可以通过初始化参数使用multiprocessing.Pool来完成:

import os, sys, multiprocessing

def square(num=None):
    if not num:
        num = int(raw_input('square what? ')) 
    return num ** 2

def initialize(fd):
    sys.stdin = os.fdopen(fd)

initargs = [sys.stdin.fileno()]
pool = multiprocessing.Pool(initializer=initialize, initargs=initargs)
pool.apply(square, [3])
pool.apply(square)

以上示例将打印数字9,然后输入提示,然后输入输入数字的平方。

请注意不要让多个子进程同时从同一个描述符中读取,否则可能会让人感到困惑。

答案 3 :(得分:0)

您可以使用线程并将其全部保存在同一进程中:

from multiprocessing import Queue
from Queue import Empty
from threading import Thread

def sub_proc(q):
    some_str = ""
    while True:
        some_str = raw_input("> ")
        if some_str.lower() == "quit":
            return
        q.put_nowait(some_str)

if __name__ == "__main__":
    q = Queue()
    qproc = Thread(target=sub_proc, args=(q,))
    qproc.start()
    qproc.join()

    while True:
        try:
            print q.get(False)
        except Empty:
            break