【问题标题】:multiprocessing pool example does not work and freeze the kernel多处理池示例不起作用并冻结内核
【发布时间】:2019-03-12 14:10:09
【问题描述】:

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

最小的工作示例:

from multiprocessing import Pool

def f(x):
  return x*x

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

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

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

【问题讨论】:

    标签: python windows parallel-processing multiprocessing python-multiprocessing


    【解决方案1】:

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

    他们需要导入f,因为Windows 不支持fork 作为新进程的启动方法(仅spawn)。必须从头开始一个新的 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))) 
    

    当与“spawn”或“forkserver”启动方法而不是默认的“fork”一起使用时,在 Windows 和 Unix-y 系统上进行多处理时,必须像这样分离代码。一般来说,start-methods可以用multiprocessing.set_start_method(method)修改。

    由于Python 3.8ma​​cOS 也默认使用“spawn”而不是“fork”。

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

    【讨论】:

      猜你喜欢
      • 2014-08-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-17
      • 2021-09-30
      相关资源
      最近更新 更多