在多处理中,我是否需要手动调用pool.terminate?

时间:2015-06-12 14:41:20

标签: python multiprocessing python-multiprocessing

以下2个片段似乎有相同的行为:

def sqr(a):
    time.sleep(1.2)
    print 'local {}'.format(os.getpid())
    if a == 20:
        raise Exception('fff')
    return a * a

pool = Pool(processes=4)

A:

try:
    r = [pool.apply_async(sqr, (x,)) for x in range(100)]

    pool.close()

    for item in r:
        item.get(timeout=999999)

except:
    pool.terminate()
    raise

finally:
    pool.join()


print 'main {}'.format(os.getpid())

B:

r = [pool.apply_async(sqr, (x,)) for x in range(100)]

pool.close()

for item in r:
    item.get(timeout=999999)

pool.join()

最初我认为如果我不做terminate,即使主进程退出,所有其他进程也会在后台运行。但是我检查了htop,一旦发现异常,所有子进程都会退出。

1 个答案:

答案 0 :(得分:2)

当您致电pool.close()时,您告诉Pool不再向其发送任务。这允许它在处理完当前任务队列后立即关闭其工作进程 - 不需要显式terminate()调用。这在文档中提到:

  

<强> close()

     

防止将更多任务提交到池中。完成所有任务后,工作进程将退出。

请注意,任务成功完成或抛出异常并不重要;无论哪种方式,任务都已完成。

此外,Pool中的所有工作进程都以daemon=True启动,这意味着一旦父进程准备好退出,它们就会被终止。在您的情况下,您正在对正在处理的每个项目调用get(),这将导致在父项中重新引发子项中引发的异常。当发生这种情况时,父进程退出,这将自动终止所有工作进程。