为何multiprocessing在__main__.py中无法正常运行?
问题原因与解释
1. multiprocessing子进程的模块依赖逻辑
multiprocessing启动子进程时,必须能访问主进程中定义的函数(比如示例里的f)。在Windows的spawn模式(或手动指定spawn的Unix系统)下,子进程会启动全新Python解释器,重新导入主模块并跳过if __name__ == '__main__'代码块;Unix默认的fork模式虽不重新导入,但也依赖模块结构的正确性。
2. main.py的模块命名特殊性
当你运行python foo(目录)或python -m foo时:
- 主进程中,
foo/__main__.py被当作__main__模块执行(而非foo.__main__)。 - 子进程启动时,尝试导入主模块以获取
f函数,但子进程的__main__是自身的入口,无法关联到父进程的foo/__main__.py,因此找不到f,抛出AttributeError。
3. 无限循环与进程暴涨的原因
multiprocessing.Pool会自动重启崩溃的工作进程,子进程不断因找不到f崩溃,Pool就不断创建新进程,导致进程数持续增加;此时按Ctrl+C触发的KeyboardInterrupt会和子进程报错交替出现,形成无限循环。
4. 单独file.py能正常运行的原因
运行python file.py或python -m file时,主进程的模块名为__main__,但子进程会将其识别为file模块,可正常导入并找到f函数,因此子进程能正常工作,Pool运行无问题。
修复方案
把业务逻辑从__main__.py拆分到包内的独立模块,比如:
# foo/funcs.py def f(x): return x*x
# foo/__main__.py from multiprocessing import Pool from .funcs import f if __name__ == '__main__': with Pool(5) as p: print(p.map(f, [1, 2, 3]))
这样子进程可通过foo.funcs导入f,不再依赖__main__模块,即可正常运行。
内容的提问来源于stack exchange,提问作者user3290525
相关产品推荐
相关产品推荐

