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._clearpool.restart 才能终止(或重新启动)池。 pathos.multiprocessing 中的接口已弃用...首选接口是pathos.pools.ProcessPool。该池应该有一个_clear 和一个restart 方法。请注意,这与pathos.multiprocessing.ProcessPoolpathos.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多处理,在循环中多次使用池在第一次迭代后卡住的主要内容,如果未能解决你的问题,请参考以下文章

Python多处理池在加入时挂起?

C++线程一次创建 多次使用 避开循环场景中 线程多次创建销毁的开销

在 python/Django 中多次迭代 json 对象

python第七课——循环结构 while

如何使用python语句跳出循环

netcdf4-python:随着从 netcdf 对象多次调用切片数据,内存增加