多处理池示例不起作用并冻结内核

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多处理池示例不起作用并冻结内核相关的知识,希望对你有一定的参考价值。

我正在尝试并行化脚本,但由于未知原因,内核只是冻结而没有抛出任何错误。

最小的工作范例:

from multiprocessing import Pool

def f(x):
  return x*x

p = Pool(6)
print(p.map(f, range(10)))   

有趣的是,如果我在另一个文件中定义我的函数然后导入它,一切正常。如何在不需要其他文件的情况下使其工作?

我使用spyder(anaconda),如果我从windows命令行运行我的代码,我会得到相同的结果。

答案

发生这种情况是因为当您的子进程导入f时,您没有保护代码的过程部分不被重新执行。

他们需要导入f,因为Windows不支持forking作为新进程的启动方法(仅生成)。必须从头开始新的Python进程,导入f,此导入还将触发在所有子进程中创建另一个池......以及它们的子进程及其子进程。

要防止这种递归,您必须在上部(应该在导入上运行)和下部之间插入一个if __name__ == '__main__': -line,它应该只在脚本作为主脚本执行时运行(仅适用于父脚本)。

from multiprocessing import Pool

def f(x):
  return x*x

if __name__ == '__main__': # protect your program's entry point

    p = Pool(6)
    print(p.map(f, range(10))) 

当使用'forkserver'start-method而不是默认的'fork'时,在Windows和Unix-y系统上进行多处理是必需的。

一般来说,将上层“定义”中的任何脚本分开并将“执行作为主”分开是一种很好的做法,以使代码可导入而无需执行部分仅在作为顶级脚本运行时相关的部分。最后但同样重要的是,当您不混合定义和执行时,它有助于理解程序的控制流程。

以上是关于多处理池示例不起作用并冻结内核的主要内容,如果未能解决你的问题,请参考以下文章

python 多处理池示例,使用3D numpy数组作为输入,在计算密集型堆栈上使用所有CPU内核。

为啥多处理锁获取不起作用?

片段 getActivity 不起作用

Python中的分布式多处理池

重新加载片段不起作用

从父片段到选项卡片段的接口侦听器不起作用