python multiprocessing on windows, if __name__ == “__main__”
在Windows7(64位)上运行python 2.7。
在读取库模块multiprocessing的文档时,它会多次说明__main__模块的重要性,包括条件(尤其是在Windows中):
1 2
| if __name__ =="__main__":
# create Process() here |
我的理解是,您不希望在模块的全局命名空间中创建process()实例(因为当子进程导入模块时,他会无意中生成另一个)。
但是,我不必将流程管理器放在包执行层次结构的最顶层(在父级中执行)。只要我的process()是在类方法中创建、管理和终止的,甚至是在函数闭包中。只是不在顶级模块命名空间中。
我是否正确理解此警告/要求?
编辑
在前两个回复之后,我添加了这个报价。这在2.7文档的第16.6节多处理介绍中。
Note: Functionality within this package requires that the __main__ module be importable by the children. This is covered in Programming
guidelines however it is worth pointing out here.This means that some
examples, such as the multiprocessing.Pool examples will not work in
the interactive interpreter...
- 迂腐的说明:当代码实际运行时,if __name__ == '__main__':中的变量仍然在模块的名称空间中。但是,在导入模块时不会执行代码。(即,我相信,如果导入程序的主模块,可以从主模块中检索变量作为模块属性。)
- 所以在if中创建的@millimoose变量对Windows机器上所有生成的进程都是可访问的,对吗?即使它们没有在if之外宣布?
- @卡提克-我不确定我是否理解这个问题,反正已经三年了。我认为他们是可以接近的,但他们的价值观是假的。我建议您编写一些测试代码来了解您的想法,并在上面发布一个新问题,以便您对它有任何特定的问题。
您不必从模块的"顶层"调用Process()。从类方法调用Process是非常好的。
唯一需要注意的是,如果或在导入模块时,您不能允许调用Process()。
由于Windows没有fork,因此多处理模块启动一个新的python进程并导入调用模块。如果在导入时调用Process(),那么这将引发无限多的新进程(或者直到您的计算机资源耗尽)。这就是隐藏对Process()内部调用的原因。
1
| if __name__ =="__main__" |
由于此if-statement中的语句在导入时不会被调用。
- 我相信我理解你的观点。我对最初的问题做了一个编辑,更好地说明了我的困惑。
- 问:为什么需要进口__main__?.A:在Windows上,调用Process()会导致调用模块被导入。在使用multiprocessing时,需要编写代码,期望调用模块能够被导入。
- 我想我分析过度了。我将计划导入我的多处理模块。实际上,它永远不会被执行,因为我的程序也要导入它,并且必须在创建任何process()实例之前与工厂类进行交互。
- 这是否意味着joblib文档中的警告,即不应在if __name__ == '__main__'块之外执行任何代码,这是一种过度杀戮?
- @子源:重要的是你要了解在if-block之外的代码会发生什么,特别是在windows上,每个生成的进程都会重新导入调用模块,从而重新执行if-block之外的所有代码。joblib文件说,"只有进口和定义"。定义可以包括变量和函数的定义。只要确保不要在if-block之外生成子流程,因为(在Windows上)肯定会导致叉式炸弹。
- @unutbu:如果我有一个在if-block中创建的变量,但需要由稍后传递给工作人员池的函数使用,该怎么办?基本上,这是否适用于Windows:if __name__ == '__main__': var = 10<>with Pool(2) as p: p.map(partial(my_funct, var), task_list)?(注意,with Pool...在if-block内)
如果脚本是通过python foo.py或python -m foo直接执行的,那么__name__仅等于"__main__"。这确保了如果脚本作为模块导入,则不会调用Process()。
- 所以多处理不能用在一个模块中?
- @可以,但对Process()的实际构造函数调用必须包装为"singleton命令"。这是因为Windows不仅要克隆该进程,而且必须重新执行Python解释器的副本,这意味着"主模块"将被导入两次。基本上,将导入"活动"保持在最低限度。导入完成后,您可以对模块中的类和函数执行任何您想要的操作。
- @用户2097818能否更详细地解释一下"singleton命令"的含义?本质上,我想知道是否可以生成一个函数(在我将导入的某些模块中定义)并执行该函数,而不将其包装为内部使用多处理的"if name='main'"。
- 学究一点,难道__name__ == '__main__'对__main__.py不总是正确的吗?