为什么billiard多进程模块需要"if __name__=='__main__'"这一行?
如果我有以下这段代码:
def f():
print 'ok!'
import sys
sys.exit()
if __name__=='__main__':
import billiard
billiard.forking_enable(0)
p = billiard.Process( target=f)
p.start()
while p.is_alive():
pass
这个脚本按预期运行,打印出“ok!”然后结束。但是如果我去掉了 if __name__=='__main__':
这一行,并且把后面的代码缩进去,我的电脑(OS X)就会疯狂运转,不停地生成很多Python进程,直到我用 killall Python
命令强制结束它们。你知道这是怎么回事吗?
(对于那些把这个标记为重复问题的人,请注意,虽然其他问题问的是 if __name__=='__main__'
的一般目的,但我具体想知道的是,为什么不使用它会导致如此意外的行为)
1 个回答
8
你通过这一行代码禁用了 fork
功能:
billiard.forking_enable(0)
这意味着库需要生成(而不是使用 fork)你的子进程,并让它重新导入 __main__
模块来运行 f
,就像 Windows 系统那样。如果没有 if __name__ ...
的保护,子进程重新导入 __main__
模块时,也会重新运行你创建 billiard.Process
的代码,这样就会导致无限循环。
如果你保持 fork
功能开启,子进程中的重新导入就不是必须的,所以无论有没有 if __name__ ...
的保护,所有东西都能正常工作。