我们啥时候应该调用 multiprocessing.Pool.join?
Posted
技术标签:
【中文标题】我们啥时候应该调用 multiprocessing.Pool.join?【英文标题】:When should we call multiprocessing.Pool.join?我们什么时候应该调用 multiprocessing.Pool.join? 【发布时间】:2016-11-11 07:28:18 【问题描述】:我使用'multiprocess.Pool.imap_unordered'如下
from multiprocessing import Pool
pool = Pool()
for mapped_result in pool.imap_unordered(mapping_func, args_iter):
do some additional processing on mapped_result
我是否需要在 for 循环之后调用 pool.close
或 pool.join
?
【问题讨论】:
一旦我启动了所有池线程,我通常会调用pool.join()
然后pool.close()
,但我没有尝试使用pool.imap_unordered()
作为可迭代对象。
调用 join 或 close 有什么意义?我没有打电话给他们,我的代码似乎工作正常。但是,我担心不调用这些会导致僵尸进程或其他微妙的事情。
【参考方案1】:
不,你没有,但如果你不再使用游泳池可能是个好主意。
pool.close
或 pool.join
的原因由 Tim Peters 在this SO post 中说得很好:
对于 Pool.close(),您应该在 - 并且仅在 - 您永远不会向 Pool 实例提交更多工作时调用它。所以 Pool.close() 通常在主程序的可并行部分完成时调用。然后,当所有已分配的工作都完成时,工作进程将终止。
调用 Pool.join() 来等待工作进程终止也是一个很好的做法。除其他原因外,通常没有好的方法来报告并行代码中的异常(异常发生在与您的主程序正在执行的操作模糊相关的上下文中),并且 Pool.join() 提供了一个可以报告发生的一些异常的同步点在您永远不会看到的工作进程中。
【讨论】:
先调用一个会更好吗? 似乎人们喜欢先调用pool.close()
,然后再调用pool.join()
。这允许您在 pool.close()
和 pool.join()
之间添加不需要等待池完成执行的工作。
只是为了添加到@Bamcclur 的评论 - 首先调用pool.close()
不仅仅是一个好主意,它实际上是强制性的。来自the docs :在使用join()
之前,必须先致电close()
或terminate()
。
@Bogd 但是为什么它是强制性的?请你回答this的问题好吗?
agdhruvs 问题的答案会很棒!【参考方案2】:
当我没有使用pool.close()
和pool.join()
时,我遇到了与Memory usage keep growing with Python's multiprocessing.pool 相同的内存问题,而pool.map()
使用了一个计算Levenshtein 距离的函数。该函数运行良好,但在 Win7 64 机器上没有正确收集垃圾,并且每次调用该函数时内存使用量都会不断增长,直到整个操作系统崩溃。这是修复泄漏的代码:
stringList = []
for possible_string in stringArray:
stringList.append((searchString,possible_string))
pool = Pool(5)
results = pool.map(myLevenshteinFunction, stringList)
pool.close()
pool.join()
关闭并加入池后,内存泄漏消失了。
【讨论】:
在添加清理代码pool.close();pool.join();
之前,我得到了 ERROR: Terminated with signal 15
,但在添加清理代码之后,我没有收到控制台消息。所以我怀疑至少在我的版本中,来自 C7 的 python 2.7,池可能以某种方式没有完全清理。以上是关于我们啥时候应该调用 multiprocessing.Pool.join?的主要内容,如果未能解决你的问题,请参考以下文章
glVertexAttribPointer() - 啥时候应该调用它?
UIViewController 的 viewDidAppear/viewDidDisappear:应该在啥时候调用这些方法?