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

Posted

技术标签:

【中文标题】将 Python Pool 与上下文管理器一起使用或关闭并加入【英文标题】:Use Python Pool with context manager or close and join 【发布时间】:2019-07-28 20:10:06 【问题描述】:

Python documentation 的示例格式为

with Pool() as p:
    p.map(do)

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

p = Pool()
p.map(do)
p.close()
p.join()

哪个更受欢迎?

【问题讨论】:

【参考方案1】:

我认为使用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()

编辑:正如 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 之前加入 @FacundoOlano,感谢您收看这个!我已经修复了上面的异步示例。 亲爱的,我一直想知道的一件事是应该在池上下文管理器中还是在外部调用“关闭”和“加入”。有人会进一步阐明吗?真诚的 @PhilipipeRiskallaLeal 它必须在上下文中。 p 将在代码退出“with”上下文后不再存在 @ThangDo 实际上并非如此。在解释器中尝试一下:p 在上下文管理器块之后仍在范围内。

以上是关于将 Python Pool 与上下文管理器一起使用或关闭并加入的主要内容,如果未能解决你的问题,请参考以下文章

python unittest 将断言与上下文管理器结合起来

Python 上下文管理器模块--contextlib

python2.7高级编程 笔记一(Python中的with语句与上下文管理器学习总结)

python上下文管理器

Python核心技术与实战——二一|巧用上下文管理器和with语句精简代码

我可以将 with 语句与 MySQLdb.Connection 对象一起使用吗?