本文共 2921 字,大约阅读时间需要 9 分钟。
记得刚学Python的时就碰到过这个问题,结果快一年后再看仍然不能完全理解,简单做个记录,日后再补充。
下面代码会报错:
import multiprocessingimport timedef sing(): print('ing') time.sleep(1)# if __name__ == '__main__':#如果下面代码不被# if __name__ == '__main__':包裹的话,就会报错pool=multiprocessing.Pool(2)pool.apply(sing)for i in range(5): pool.apply(sing)
报错信息:
RuntimeError:
An attempt has been made to start a new process before the current process has finished its bootstrapping phase.This probably means that you are not using fork to start your
child processes and you have forgotten to use the proper idiom in the main module:if __name__ == '__main__':
freeze_support() ...The "freeze_support()" line can be omitted if the program
is not going to be frozen to produce an executable.
简单翻译下:
RuntimeError:
在当前进程完成了他的引导阶段之前试图去启动一个新进程。
这可能是表示你没有用fork方法启动子进程,并且你忘了用正确的姿势在main模块中:
if __name__ == '__main__':
freeze_support() ...如果程序不会被冻结以生成可执行文件The "freeze_support()" 这行代码可以被忽略
先说解决方法:
代码放在 if __name__ == '__main__':下执行就行了,如下:
import multiprocessingimport timedef sing(): print('ing') time.sleep(1)if __name__ == '__main__': pool=multiprocessing.Pool(2) pool.apply(sing) for i in range(5): pool.apply(sing)
至于具体为什么,根本原因,查看半天资料也没完全理解,大致就是windows创建进程没有fork方法,默认是spawn,而linux创建进程默认是fork方法。为了什么进程保护,代码必须放在if __name__ == '__main__':下面。想要完全理解估计还要深入理解进程的概念,什么僵尸进程,孤儿进程类似的吧。
官方文档:
Safe importing of main module
Make sure that the main module can be safely imported by a new Python interpreter without causing unintended side effects (such a starting a new process).
For example, using the spawn or forkserver start method running the following module would fail with a :
from multiprocessing import Processdef foo(): print('hello')p = Process(target=foo)p.start()Instead one should protect the “entry point” of the program by using
if __name__ == '__main__':
as follows:from multiprocessing import Process, freeze_support, set_start_methoddef foo(): print('hello')if __name__ == '__main__': freeze_support() set_start_method('spawn') p = Process(target=foo) p.start()(The
freeze_support()
line can be omitted if the program will be run normally instead of frozen.)This allows the newly spawned Python interpreter to safely import the module and then run the module’s
foo()
function.Similar restrictions apply if a pool or manager is created in the main module.
有道翻译一下:
确保新的Python解释器可以安全地导入主模块,而不会引起意外的副作用(这样就可以启动一个新进程)。
例如,使用spawn或forkserver start方法运行以下模块会失败,报错:RuntimeError:
相反,应该使用if……name__ == ' _main__'来保护程序的“入口点”:
(如果程序将正常运行而不是冻结,则可以省略freeze_support()行。)
这允许新生成的Python解释器安全地导入模块,然后运行模块的foo()函数。
如果在主模块中创建池或管理器,也会应用类似的限制。
stackoverflow:
On Windows the subprocesses will import (i.e. execute) the main module at start. You need to insert an
if __name__ == '__main__':
guard in the main module to avoid creating subprocesses recursively.
在windows系统中在最初的时候子进程会导入main模块,你需要插入if __name__ == '__main__',保护main模块为了避免递归的创建子进程。
暂时也就理解成这样,欢迎大佬指点
转载地址:http://vcxws.baihongyu.com/