我是否需要在多处理异常时手动调用 pool.terminate?

Do I need to call pool.terminate manually upon excepton in 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)

甲:

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())

乙:

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 并且似乎所有子进程都在异常被触发后立即退出。

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

close()

Prevents any more tasks from being submitted to the pool. Once all the tasks have been completed the worker processes will exit.

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

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