为什么billiard多进程模块需要"if __name__=='__main__'"这一行?

3 投票
1 回答
2217 浏览
提问于 2025-04-30 22:17

如果我有以下这段代码:

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__ ... 的保护,所有东西都能正常工作。

撰写回答