Python多处理,在循环中多次使用池在第一次迭代后卡住
Posted
技术标签:
【中文标题】Python多处理,在循环中多次使用池在第一次迭代后卡住【英文标题】:Python multiprocessing, using pool multiple times in a loop gets stuck after first iteration 【发布时间】:2018-12-15 01:22:43 【问题描述】:我有以下情况,我在 for 循环中创建了一个池,如下所示(我知道这不是很优雅,但出于酸洗的原因我必须这样做)。假设pathos.multiprocessing
相当于python 的multiprocessing
库(因为它取决于一些细节,与这个问题无关)。
我有以下要执行的代码:
self.pool = pathos.multiprocessing.ProcessingPool(number_processes)
for i in range(5):
all_responses = self.pool.map(wrapper_singlerun, range(self.no_of_restarts))
pool._clear()
现在我的问题是:循环成功运行了第一次迭代。但是,在第二次迭代时,算法突然停止(没有完成pool.map
操作。我怀疑生成了僵尸进程,或者该进程不知何故是switched
。下面你会发现我到目前为止所尝试的所有内容。
for i in range(5):
pool = pathos.multiprocessing.ProcessingPool(number_processes)
all_responses = self.pool.map(wrapper_singlerun, range(self.no_of_restarts))
pool._clear()
gc.collect()
for p in multiprocessing.active_children():
p.terminate()
gc.collect()
print("We have so many active children: ", multiprocessing.active_children()) # Returns []
上面的代码在我的 mac 上运行良好。但是,当我将它上传到具有以下规格的集群上时,我得到了它在第一次迭代后卡住的错误:
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=18.04
DISTRIB_CODENAME=bionic
DISTRIB_DESCRIPTION="Ubuntu 18.04 LTS"
这是the link to the pathos'多处理库文件是
【问题讨论】:
嗨,我是pathos
作者。 pathos.multiprocessing
以两种方式提供了增强的Pool
:(1) 更好的序列化,以及 (2) 初始化。如果你只是在寻找更好的序列化,我建议你使用pathos.pools._ProcessPool
,它具有multiprocessing
的确切接口和规格,但具有更好的序列化。如果您正在寻找其他 pathos
功能,那么您应该知道 pathos
池会被保留,除非明确销毁。您必须在上面使用的池上执行 pool._clear
或 pool.restart
才能终止(或重新启动)池。
pathos.multiprocessing
中的接口已弃用...首选接口是pathos.pools.ProcessPool
。该池应该有一个_clear
和一个restart
方法。请注意,这与pathos.multiprocessing.ProcessPool
和pathos.multiprocessing.ProcessingPool
是同一个对象...为了向后兼容,我一直保留这两个对象。
很难调试你所看到的,因为你没有提供其他人可以运行的代码,你看到的错误被证明了。你能做到吗?就目前而言,很难说出你想要做什么。
如果是这种情况,您应该能够通过限制池中的进程数量来测试该理论,同时执行clear
以关闭循环中的每个Pool
。这将限制活动进程的数量。你可以试试ProcessPool(1)
或类似的东西。
@DaveTheAl 你有没有解决过挂起的问题?我相信我遇到了同样的问题。
【参考方案1】:
我假设您正试图通过某个函数调用它,而这不是正确的使用方法。
你需要用 :
包裹它if __name__ == '__main__':
for i in range(5):
pool = pathos.multiprocessing.Pool(number_processes)
all_responses = pool.map(wrapper_singlerun,
range(self.no_of_restarts))
如果您不这样做,它将继续创建自己的副本并开始将其放入堆栈中,最终将填满堆栈并阻塞所有内容。它在mac上工作的原因是它有fork而windows没有它。
【讨论】:
1.) 所以区别是 name == "main"?不幸的是,这不是我可以应用的东西,因为我的脚本只是另一个库的一个模块,它控制着我的函数的执行方式。 2.) 另一个没有运行的平台不是windows,而是ubuntu(在最后标记) 您的主脚本,即您首先调用的脚本,应该包含在if name == 'main'
子句中。以上是关于Python多处理,在循环中多次使用池在第一次迭代后卡住的主要内容,如果未能解决你的问题,请参考以下文章