以下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
,一旦发现异常,所有子进程都会退出。
答案 0 :(得分:2)
当您致电pool.close()
时,您告诉Pool
不再向其发送任务。这允许它在处理完当前任务队列后立即关闭其工作进程 - 不需要显式terminate()
调用。这在文档中提到:
<强>
close()
强>防止将更多任务提交到池中。完成所有任务后,工作进程将退出。
请注意,任务成功完成或抛出异常并不重要;无论哪种方式,任务都已完成。
此外,Pool
中的所有工作进程都以daemon=True
启动,这意味着一旦父进程准备好退出,它们就会被终止。在您的情况下,您正在对正在处理的每个项目调用get()
,这将导致在父项中重新引发子项中引发的异常。当发生这种情况时,父进程退出,这将自动终止所有工作进程。