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

时间:2018-10-07 21:49:40

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

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

最小工作示例:

from multiprocessing import Pool

def f(x):
  return x*x

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

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

我使用spyder(anaconda),如果从Windows命令行运行代码,则结果相同。

1 个答案:

答案 0 :(得分:3)

之所以会发生这种情况,是因为在子进程导入f时,您没有保护代码的程序部分免于重新执行。

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

为防止这种递归,您必须在上部(应该在导入时运行)和下部(仅当您的脚本作为主脚本执行时才运行)之间插入if __name__ == '__main__':行。父母的情况)。

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”启动方法(而非默认的“ fork”)一起使用时,在Windows和Unix-y系统上的多处理中必须这样分隔代码。

通常的一个好习惯是,将“ any ”脚本分隔为较高的“ definition”和较低的“ execution as main”,以使代码可导入而无需不必要的部分执行,而仅当作为顶层脚本运行时才有意义。最后但并非最不重要的一点是,当您不混合定义和执行时,它有助于理解程序的控制流。