将 Python 池与上下文管理器一起使用或关闭并加入

Seu*_*ung 15 python pool

Python文档的示例格式为

with Pool() as p:
    p.map(do)
Run Code Online (Sandbox Code Playgroud)

但我看到很多人使用下面的格式。

p = Pool()
p.map(do)
p.close()
p.join()
Run Code Online (Sandbox Code Playgroud)

哪个更受欢迎?

Nik*_*nar 18

我认为Pool用作上下文管理器(例如,with ...)是可取的。它是对 的更新Pool,它可以让您更清晰地封装池的生命周期。

需要注意的一件事是,当上下文管理器退出时,它将终止池​​和任何正在进行的任务。这意味着p.join()在某些情况下您仍然希望这样做。您的示例不需p.map要这样做,因为无论如何都会阻止执行,直到任务完成:

map() 内置函数的并行等效项(尽管它仅支持一个可迭代参数)。它阻塞直到结果准备好。

https://docs.python.org/3.7/library/multiprocessing.html#multiprocessing.pool.Pool.map

因此,在第二个示例中,调用.join()是不必要的,因为它.map()会阻塞直到所有任务完成。

但是,使用.map_async.join很有用:

with Pool() as p:
    p.map_async(do_something, range(100))
    # Do something else while tasks are running
    p.close()
    p.join()
Run Code Online (Sandbox Code Playgroud)

编辑:正如 Facundo Olano 指出的那样,.close()必须始终在之前调用.join(),如文档中所述:

等待工作进程退出。在使用 join() 之前必须调用 close() 或 terminate() 。

https://docs.python.org/3.7/library/multiprocessing.html#multiprocessing.pool.Pool.join

  • 我认为`p.close()`在异步示例中也是必要的,文档说“在使用join()之前必须调用close()或terminate()”,如果我尝试之前加入,我可以确认有错误在 python 3.6 中关闭 (3认同)