Pool.map
将在主进程中处理输入列表(或其他可迭代),以便一次将列表的一个*成员交给每个进程。因此,您的示例等效于以下内容:
import multiprocessing
import fileinput
def test(line):
print line
input = []
for line in fileinput.input():
input.append(line)
p = multiprocessing.Pool()
p.map(test, input)
其中子进程确实没有从stdin
.
* 除非您指定 achunksize
在这种情况下,它会一次将一组列表成员交给每个进程。
话虽如此,子进程无法访问是不正确的stdin
。如果这通常是正确的,那么例如 UNIX shell 将没有多大用处。实际上,子进程继承其父进程的文件描述符。因此,父母和孩子都可以从同一个输入源进行阅读。但问题是一段输入数据只能被读取一次,所以问题不在于stdin
子进程的访问,而是决定哪个进程读取什么数据。在许多情况下,这很困难,因此不可靠(例如,如果您通过缓冲区读取数据,例如通过许多编程语言的标准库子例程)。
我想,出于上述原因,multiprocessing
模块的作者决定在子进程中关闭sys.stdin
(例如,您可以读取的标准库对象stdin
)并强制您以更安全的方式(例如 via multiprocessing.Queue
)向目标函数提供其输入数据. 但是有一个解决方法,只要您确切地知道您的子进程将如何访问stdin
,这也适用于您在父进程中打开的任何文件:
import os, sys, multiprocessing
def square(num):
if num == 3:
num = int(raw_input('square what? '))
return num ** 2
def initialize(fd):
sys.stdin = os.fdopen(fd)
initargs = [sys.stdin.fileno()]
pool = multiprocessing.Pool(5, initialize, initargs)
因此,例如,如果我们将 1 到 10 的数字发送到池中,五个进程中的每一个都会收到一个数字,一次一个,但获得数字 3 的进程将提示输入:
>>> pool.map(square, range(10)))
square what? 9
[0, 1, 4, 81, 16, 25, 36, 49, 64, 81]
请注意不要让多个子进程同时从同一个描述符中读取,否则事情可能会变得......混乱。