多处理池示例不起作用并冻结内核
multiprocessing pool example does not work and freeze the kernel
我正在尝试并行化脚本,但由于未知原因,内核只是冻结而没有抛出任何错误。
最小工作示例:
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 不支持分叉作为新进程的启动方法(仅 spawn )。一个新的 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)))
在 Windows 和 Unix-y 系统上使用 'spawn' 或 'forkserver' 启动方法而不是默认的 'fork' 启动方法时,必须像这样分隔代码.一般来说,start-methods可以修改为multiprocessing.set_start_method(method)
.
由于 Python 3.8,macOS 也默认使用 'spawn' 而不是 'fork'。
将 any 脚本分隔在上层“定义”和下层“作为主要执行”中是一个很好的做法,以使代码可导入而不会不必要地执行部分仅在 运行 作为顶级脚本。最后但同样重要的是,当您不混合定义和执行时,它有助于理解程序的控制流。
我正在尝试并行化脚本,但由于未知原因,内核只是冻结而没有抛出任何错误。
最小工作示例:
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 不支持分叉作为新进程的启动方法(仅 spawn )。一个新的 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)))
在 Windows 和 Unix-y 系统上使用 'spawn' 或 'forkserver' 启动方法而不是默认的 'fork' 启动方法时,必须像这样分隔代码.一般来说,start-methods可以修改为multiprocessing.set_start_method(method)
.
由于 Python 3.8,macOS 也默认使用 'spawn' 而不是 'fork'。
将 any 脚本分隔在上层“定义”和下层“作为主要执行”中是一个很好的做法,以使代码可导入而不会不必要地执行部分仅在 运行 作为顶级脚本。最后但同样重要的是,当您不混合定义和执行时,它有助于理解程序的控制流。