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