它只是时机。 Windows需要在Pool
中产生4个进程,然后需要启动,初始化并准备从Queue
消耗。在Windows上,这要求每个子进程重新导入__main__
模块,并要求Pool
内部使用的Queue
实例在每个子进程中取消选中。这需要花费很少的时间。事实上,当你在Pool
的所有进程运行起来之前都执行了两个map_async()
调用时,已经足够长了。你可以看到这一点,如果你在添加每个工人运行一些跟踪功能的Pool
:
while maxtasks is None or (maxtasks and completed < maxtasks):
try:
print("getting {}".format(current_process()))
task = get() # This is getting the task from the parent process
print("got {}".format(current_process()))
输出:
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
process id = 5145
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
process id = 5145
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
result = [121]
result1 = [100]
getting <ForkServerProcess(ForkServerPoolWorker-2, started daemon)>
getting <ForkServerProcess(ForkServerPoolWorker-3, started daemon)>
getting <ForkServerProcess(ForkServerPoolWorker-4, started daemon)>
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
正如你所看到的,Worker-1
启动和工人之前消耗这两个任务2-4尝试从Queue
消耗。如果添加sleep
叫你实例化的主要工序中Pool
之后,但调用map_async
之前,你会看到不同的流程处理每一个请求:
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
getting <ForkServerProcess(ForkServerPoolWorker-2, started daemon)>
getting <ForkServerProcess(ForkServerPoolWorker-3, started daemon)>
getting <ForkServerProcess(ForkServerPoolWorker-4, started daemon)>
# <sleeping here>
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
process id = 5183
got <ForkServerProcess(ForkServerPoolWorker-2, started daemon)>
process id = 5184
getting <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
getting <ForkServerProcess(ForkServerPoolWorker-2, started daemon)>
result = [121]
result1 = [100]
got <ForkServerProcess(ForkServerPoolWorker-3, started daemon)>
got <ForkServerProcess(ForkServerPoolWorker-4, started daemon)>
got <ForkServerProcess(ForkServerPoolWorker-1, started daemon)>
got <ForkServerProcess(ForkServerPoolWorker-2, started daemon)>
(请注意,附加"getting
/"got"
语句你看到的是哨兵被发送到每个进程优雅地关闭它们)。
在Linux上使用Python 3.x,我可以使用'spawn'
和'forkserver'
上下文重现此行为,但不能使用'fork'
。大概是因为分娩孩子的过程比产卵他们并且重新进口__main__
要快得多。
你使用的是Windows? – dano 2014-11-01 22:28:25
@ dano-yes ....., – user1050619 2014-11-01 22:29:14