为啥 Python 的多处理模块在 Windows 上启动新进程时会导入 __main__?
Posted
技术标签:
【中文标题】为啥 Python 的多处理模块在 Windows 上启动新进程时会导入 __main__?【英文标题】:Why does Python's multiprocessing module import __main__ when starting a new process on Windows?为什么 Python 的多处理模块在 Windows 上启动新进程时会导入 __main__? 【发布时间】:2012-12-19 23:11:23 【问题描述】:我正在为我的初学者学生使用一个库,并且我正在使用 Python 中的多处理模块。我遇到了这个问题:importing and using a module that uses multiprocessing without causing infinite loop on Windows
例如,假设我有一个模块mylibrary.py
:
# mylibrary.py
from multiprocessing import Process
class MyProcess(Process):
def run(self):
print "Hello from the new process"
def foo():
p = MyProcess()
p.start()
还有一个调用这个库的主程序:
# main.py
import mylibrary
mylibrary.foo()
如果我在 Windows 上运行 main.py
,它会尝试将 main.py 导入新进程,这意味着代码会再次执行,从而导致进程生成的无限循环。我可以这样修复它:
import mylibrary
if __name__ == "__main__":
mylibrary.foo()
但是,这对初学者来说相当混乱,而且似乎没有必要。新进程是在mylibrary
中创建的,那为什么新进程不直接导入mylibrary
呢?有没有办法解决这个问题而无需更改main.py
?
顺便说一下,我使用的是 Python 2.7。
【问题讨论】:
【参考方案1】:Windows 没有fork
,因此无法像现有进程一样创建新进程。所以子进程要再次运行你的代码,但是现在你需要一种方法来区分父进程和子进程,__main__
就是它了。
这在此处的文档中有介绍:http://docs.python.org/2/library/multiprocessing.html#windows
我不知道另一种构造代码以避免分叉炸弹效应的方法。
【讨论】:
我确定我遗漏了一些东西,但我的问题是为什么子进程必须再次运行所有代码。为什么不只是启动新进程的模块? @Laura:它必须再次运行你的所有代码,因为如果没有,它就没有你的代码。子进程从头开始,如果你想让它有你的功能,它需要你的代码。 @NedBatchelder:这仍然不能真正回答问题。在发布的示例中,新进程只需要run
函数。为什么必须导入其他模块才能运行该功能?
@Laura:关键是,应该在其中调用该模块的上下文,主脚本所在的上下文。由于 Windows 没有 fork,它可以不仅仅是将上下文复制到新进程中,它必须调用主脚本才能再次设置它。这就是您将实际程序代码放在if __name__ == "__main__":
块中的原因。导致它的一切都只是设置环境(所有导入、函数定义等)。
@Laura 回答 为什么子进程必须再次运行所有代码 - 当您这样做时,import mylibrary
mylibrary 成为全局的一部分命名空间(shared 与 main.py)因此,当您随后调用 mylibrary.foo()
时,foo 在此命名空间中运行,这会影响其行为。为了确保 foo 在子进程中的运行方式与在主进程中的运行方式完全相同,您必须在完全相同的命名空间(环境)中运行它,唯一的方法是从头开始运行所有内容,从执行 main.py. 开始以上是关于为啥 Python 的多处理模块在 Windows 上启动新进程时会导入 __main__?的主要内容,如果未能解决你的问题,请参考以下文章