在Windows上的python中使用多处理时,应该保护程序的入口点.文档说"确保新的Python解释器可以安全地导入主模块,而不会导致意外的副作用(例如启动新进程)".任何人都可以解释这究竟是什么意思?
该multiprocessing
模块通过创建将导入模块的新Python进程来工作.如果您没有添加__name__== '__main__'
保护,那么您将进入一个永无止境的新流程创建循环.它是这样的:
导入模块并在导入期间执行导致multiprocessing
生成4个新进程的代码.
这4个新进程依次导入模块并在导入期间执行代码,导致multiprocessing
产生16个新进程.
这16个新进程依次导入模块并在导入期间执行代码,导致multiprocessing
产生64个新进程.
好吧,希望你能得到这张照片.
因此,我们的想法是确保生成的过程只发生一次.用__name__== '__main__'
保护的成语最容易实现这一点.
在你已经得到的好答案上稍微扩展一下,如果你了解Linux-y系统的功能,它会有所帮助.他们使用生成新流程fork()
,这有两个好的结果:
子程序中可以看到主程序中存在的所有数据结构.他们实际上处理数据的副本.
子进程fork()
在主程序之后的指令处开始执行- 因此模块中已执行的任何模块级代码都不会再次执行.
fork()
在Windows中是不可能的,因此在Windows上,每个子进程都会重新导入每个模块.所以:
在Windows上,子进程看不到主程序中存在的数据结构; 和,
所有模块级代码都在每个子进程中执行.
因此,您需要考虑一下您只想在主程序中执行哪些代码.最明显的例子是,您希望创建子进程的代码仅在主程序中运行 - 因此应该受到保护__name__ == '__main__'
.对于一个更微妙的示例,请考虑构建一个巨大的列表的代码,您打算将其传递给工作进程以进行爬网.你可能也希望保护它,因为在这种情况下没有必要让每个工作进程浪费RAM和时间来构建他们自己无用的巨型列表副本.
请注意,__name__ == "__main__"
即使在Linux-y系统上使用也是一个好主意,因为它使预期的工作分工更加清晰.并行程序可能会令人困惑 - 每一点点都有帮助;-)