在子进程中使用STDIN的Python

在子进程中使用STDIN的Python,python,process,stdin,Python,Process,Stdin,所以我有一个程序,在“main”进程中我启动了一个新的进程对象,它(我想要的)是从STDIN读取行并将它们附加到队列对象 基本的系统设置是,有一个“获取命令”的过程,用户将输入命令/查询,我需要将这些查询发送到在单独的过程中运行的其他子系统。我的想法是通过其他系统可以读取的多处理队列来共享这些数据 我所做的(重点是获取命令/查询)基本上是: def sub_proc(q): some_str = "" while True: some_str = raw_inpu

所以我有一个程序,在“main”进程中我启动了一个新的进程对象,它(我想要的)是从STDIN读取行并将它们附加到队列对象

基本的系统设置是,有一个“获取命令”的过程,用户将输入命令/查询,我需要将这些查询发送到在单独的过程中运行的其他子系统。我的想法是通过其他系统可以读取的多处理队列来共享这些数据

我所做的(重点是获取命令/查询)基本上是:

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

怎么做?

简而言之,主进程和第二个进程不共享同一个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()的两个不同结果


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

您可以使用线程并将其保持在同一进程上:

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

通过将原始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模块。我不知道它对更复杂的系统有多强大。

如果您不想像@Ashelly的答案那样将stdin传递给目标进程函数,或者只需要对许多不同的进程进行传递,您可以通过初始化器参数使用
多处理。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,然后提示输入,然后是输入数字的平方


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

本质上,我想要一个系统,用户可以在一个进程中输入文本查询/命令,并将这些查询转移到另一个进程。为什么不在主进程上读取stdin并将其推到队列中由辅助进程处理?因为系统的结构方式很难,而且似乎可以在进程之间共享相同的stdin。From:在multiprocessing.Process.\u bootstrap()方法中-这导致进程中的进程出现问题。这已更改为:sys.stdin.close()sys.stdin=open(os.devnull),但线程会受到GIL的影响(在任何给定时间只能执行一个线程)。一旦输入一个命令并将其放入队列,其他进程就可以处理该项,而“读取输入”进程可以从用户处获取下一个要处理的项/命令(或者这就是想法)。对于线程,由于与全局解释器锁(GIL)相关:注意:“类似于”