Python多进程脚本中print语句为何执行多次?
问题:multiprocessing脚本中print语句重复执行的原因
我正在编写一个使用multiprocessing模块的简单脚本,此前没有该模块的使用经验,仅在学习基础用法。但遇到了一个困惑的问题:脚本中的print语句被执行了多次。
我理解当直接运行脚本时,if __name__ == '__main__'下的代码才会运行,整个脚本应按流程执行,原本预期if块前的print语句仅执行一次。为何它会多次执行?我通常不会用这种代码结构,想了解是否if __name__存在我未知的特性,它看起来只是普通的if语句。
我不清楚原因,希望有人能给出相关见解,谢谢!我使用的是Anaconda-Spyder 5.4.3中的Python 3.11.3。
代码示例
import multiprocessing print("TEST TEST TEST") def square(x): return x * x if __name__ == '__main__': numbers = [1, 2, 3, 4, 5] with multiprocessing.Pool() as pool: results = pool.map(square, numbers) print(results)
运行结果
TEST TEST TEST [1, 4, 9, 16, 25] TEST TEST TEST TEST TEST TEST
解答
这是因为multiprocessing.Pool在创建子进程时,会完整导入当前脚本文件来复用其中的函数(比如这里的square)。
在Windows系统(Spyder运行环境通常基于Windows)中,Python的多进程采用spawn方式启动子进程:
- 主进程启动后,会创建多个子进程,每个子进程都会重新执行整个脚本的代码,包括
if __name__ == '__main__'之外的部分。 - 只有当子进程执行到
if __name__ == '__main__'判断时,因为子进程的__name__不是'__main__',才会跳过这个代码块。
你看到的额外TEST TEST TEST就是每个子进程执行脚本开头print语句的结果——默认Pool创建的子进程数量等于CPU核心数,所以你看到了2次额外输出(对应2个核心)。
解决方法很简单:把不需要被子进程执行的代码,全部放到if __name__ == '__main__'代码块内部。修改后的代码如下:
import multiprocessing def square(x): return x * x if __name__ == '__main__': print("TEST TEST TEST") numbers = [1, 2, 3, 4, 5] with multiprocessing.Pool() as pool: results = pool.map(square, numbers) print(results)
这样只有主进程会执行print语句,子进程导入脚本时只会加载square函数,不会执行print。
内容的提问来源于stack exchange,提问作者Sushi
相关产品推荐
相关产品推荐

