我正在尝试并行化脚本,但由于未知原因,内核只是冻结而没有引发任何错误。
最小工作示例:
from multiprocessing import Pool
def f(x):
return x*x
p = Pool(6)
print(p.map(f, range(10)))
有趣的是,如果我在另一个文件中定义函数然后将其导入,则一切正常。如何在不需要另一个文件的情况下使它工作?
我使用spyder(anaconda),如果从Windows命令行运行代码,则结果相同。
答案 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”,以使代码可导入而无需不必要的部分执行,而仅当作为顶层脚本运行时才有意义。最后但并非最不重要的一点是,当您不混合定义和执行时,它有助于理解程序的控制流。