Joe*_*Joe 19 python multiprocessing joblib
joblib文档包含以下警告:
在Windows下,保护代码的主循环非常重要,以避免在使用joblib.Parallel时递归生成子进程.换句话说,您应该编写如下代码:
Run Code Online (Sandbox Code Playgroud)import .... def function1(...): ... def function2(...): ... ... if __name__ == '__main__': # do stuff with imports and functions defined about ...没有代码应该在"if __name__ =='__ main__'"块之外运行,只有导入和定义.
最初,我认为这只是为了防止偶然的奇怪情况,其中函数传递给joblib.Parallel递归调用模块,这意味着它通常是良好的做法,但通常是不必要的.但是,对我而言,为什么这只会对Windows造成风险是没有意义的.此外,这个答案似乎表明,无法保护主循环导致代码运行速度比非常简单的非递归问题慢几倍.
出于好奇,我从joblib文档中运行了一个非常简单的尴尬并行循环示例,而没有保护Windows框中的主循环.我的终端被垃圾邮件发送以下错误,直到我关闭它:
ImportError: [joblib] Attempting to do parallel computing without protecting your import on a system that does not suppo
rt forking. To use parallel-computing in a script, you must protect you main loop using "if __name__ == '__main__'". Ple
ase see the joblib documentation on Parallel for more information
Run Code Online (Sandbox Code Playgroud)
我的问题是, joblib的windows实现需要在每种情况下保护主循环吗?
如果这是一个超级基本问题,请道歉.我是并行化世界的新手,所以我可能只是缺少一些基本概念,但我无法在任何地方找到这个问题.
最后,我想指出这纯粹是学术性的; 我理解为什么以这种方式编写一个代码通常是一种好习惯,并且无论joblib如何都会继续这样做.
dan*_*ano 23
这是必要的,因为Windows没有fork().由于此限制,Windows需要__main__在其生成的所有子进程中重新导入模块,以便在子进程中重新创建父进程.这意味着如果您拥有在模块级别生成新进程的代码,那么它将在所有子进程中以递归方式执行.所述if __name__ == "__main__"防护件用于防止码在从子进程被重新执行的模块范围.
这在Linux上是不必要的,因为它确实具有fork(),它允许它分叉维护父进程相同状态的子进程,而无需重新导入__main__模块.
小智 5
万一有人在 2021 年偶然发现这一点:由于 joblib>0.12 使用的新后端“loky”不再需要保护主 for 循环。见https://joblib.readthedocs.io/en/latest/parallel.html