Why does Python's multiprocessing module import __main__ when starting a new process on Windows?
我正在为我的初学者们准备一个库,我正在使用Python中的多处理模块。我遇到了这个问题:导入和使用一个模块,该模块使用多处理而不会在Windows上造成无限循环。
例如,假设我有一个模块mylibrary.py:
1 2 3 4 5 6 7 8 9 10 11
| # mylibrary.py
from multiprocessing import Process
class MyProcess(Process):
def run(self):
print"Hello from the new process"
def foo():
p = MyProcess()
p.start() |
以及一个调用这个库的主程序:
1 2 3 4 5
| # main.py
import mylibrary
mylibrary.foo() |
如果我在Windows上运行main.py,它会尝试将main.py导入新进程,这意味着代码会再次执行,从而产生无限循环的进程生成。我可以这样修复它:
1 2 3 4
| import mylibrary
if __name__ =="__main__":
mylibrary.foo() |
但是,对于初学者来说,这是非常令人困惑的,而且似乎不需要这样做。新的进程是在mylibrary中创建的,那么为什么新的进程不只是导入mylibrary呢?有没有一种方法可以解决这个问题而不必更改main.py?
顺便说一下,我使用的是python 2.7。
Windows没有fork,因此无法像现有的那样创建新的进程。所以子进程必须再次运行代码,但是现在您需要一种方法来区分父进程和子进程,而__main__就是这样。
这里的文档包括:http://docs.python.org/2/library/multiprocessing.html windows
我不知道用另一种方法来构造代码以避免分叉炸弹效应。
- 这个答案应该被接受。
- 我确信我遗漏了一些东西,但我的问题是为什么子进程必须再次运行所有代码。为什么不只是启动新流程的模块?
- @劳拉:它必须再次运行你所有的代码,因为如果没有,它就没有你的代码。子进程完全全新启动,如果您希望它具有您的函数,它需要您的代码。
- @内德巴切尔德:这还不能真正回答这个问题。在发布的示例中,新进程只需要run函数。为什么只有导入其他模块才能运行该函数?
- @Nedbatchelder:但我的观点是,我要求它执行的函数在mylibrary.py中,所以这就是它需要导入的全部内容。
- @劳拉:重点是,有一个应该在其中调用该模块的上下文,即主脚本所在的上下文。由于Windows没有fork,它不能只将上下文复制到新进程中,它必须调用主脚本,以便重新设置。这就是为什么您将实际的程序代码放在if __name__ =="__main__":块中的原因。导致它的一切都只是设置环境(所有导入、函数定义等)。
- @劳拉要回答为什么子进程必须再次运行所有代码——当您这样做时,import mylibrarymylibrary将成为全局命名空间(与main.py共享)的一部分,因此当您随后调用mylibrary.foo()时,foo将在此命名空间中运行,这会影响它的行为。为了确保foo在子进程中的运行方式与它在主进程中的运行方式完全相同,您必须在完全相同的命名空间(环境)中运行它,唯一的方法就是从一开始就运行所有内容,从main.py的执行开始。