如何在Python中无需__main__环境运行Multiprocessing Pool代码
Python multiprocessing Pool 必须包裹在
if __name__ == "__main__"中的原因 问题现象
当你在if __name__ == "__main__"环境下运行multiprocessing Pool代码时,能正常并行处理并得到预期输出;但直接调用main()时,程序会持续抛出崩溃日志。
核心原因
这是Python多进程在Windows系统(或使用spawn启动方式的系统)下的机制导致的:
- Windows没有fork系统调用,子进程启动时会重新导入整个主脚本模块来初始化运行环境。
- 如果直接写
main(),子进程导入脚本时会再次执行main(),进而再次创建Pool,触发新一轮子进程创建,形成无限递归的进程创建循环,最终导致系统资源耗尽、程序崩溃。 - 而
if __name__ == "__main__"是Python脚本的入口判断:只有当脚本作为主程序直接运行时,__name__才会等于__main__;子进程导入脚本时,__name__会是模块名,不会执行这个判断块里的代码,从而避免了无限创建子进程的问题。
代码对比
正常运行的代码
from multiprocessing import Pool import os import time def get_acord_detected_json(page_no): time.sleep(5) return page_no*page_no def main(): n_processes = 2 page_num_list = [1,2,3,4,5] print("n_processes : ", n_processes) print("page_num_list : ", page_num_list) print("CPU count : ", os.cpu_count()) t1 = time.time() with Pool(processes=n_processes) as pool: acord_js_list = pool.map(get_acord_detected_json, page_num_list) print("acord_js_list : ", acord_js_list) t2 = time.time() print("t2-t1 : ", t2-t1) if __name__=="__main__": main()
输出:
n_processes : 2 page_num_list : [1, 2, 3, 4, 5] CPU count : 8 acord_js_list : [1, 4, 9, 16, 25] t2-t1 : 15.423236846923828
导致崩溃的写法
将末尾的if __name__=="__main__": main()替换为直接调用:
main()
此时子进程启动会重复执行main(),无限创建Pool,引发崩溃。
总结
无论在Windows还是类Unix系统中,使用multiprocessing模块时,都应该把启动多进程的代码放在if __name__ == "__main__"块内,这是避免进程创建递归的标准写法,也是官方文档推荐的最佳实践。
内容的提问来源于stack exchange,提问作者Vishal Waghmare
相关产品推荐
相关产品推荐

