Python脚本在Win10与Ubuntu的VSCode中运行行为差异原因分析
问题描述
我使用VSCode 1.73.1搭配Python 3.10,运行以下脚本:
from multiprocessing import Process def foo(i): print(i) for i in range(12): Process(target=foo, args=(i,)).start()
该脚本在Ubuntu 22.04.1系统的VSCode中可正常运行,但在Windows 10系统的VSCode中运行时报错:
RuntimeError:
An attempt has been made to start a new process before the
current process has finished its bootstrapping phase.This probably means that you are not using fork to start your child processes and you have forgotten to use the proper idiom in the main module: if __name__ == '__main__': freeze_support() ...
添加提示中的if __name__ == '__main__':包裹代码后,脚本即可在Windows上正常运行。请问为何两个操作系统下会存在这种差异?
原因解释
这是因为Linux和Windows系统中,Python多进程的进程启动机制完全不同:
- Linux(Ubuntu)采用
fork机制:
当调用Process.start()时,系统会直接复制当前进程的内存空间(包括已加载的代码、变量等)来创建子进程。子进程会从fork的位置继续执行,不需要重新导入整个脚本。所以即便没有if __name__ == '__main__':的判断,子进程也不会重复执行主程序的循环逻辑,脚本能正常运行。 - Windows采用
spawn机制:
Windows没有fork系统调用,Python会启动一个全新的Python解释器进程,然后重新导入整个脚本文件来初始化子进程。如果没有if __name__ == '__main__':的判断,子进程在导入脚本时会再次执行主程序中的for循环,尝试创建新的子进程,这就会触发启动进程的递归调用,导致报错。
if __name__ == '__main__':的作用是区分脚本作为主程序运行和被其他模块导入的场景:当脚本被子进程导入时,__name__会变成子进程的模块名,不会执行if块内的代码,从而避免了递归创建进程的问题。
内容的提问来源于stack exchange,提问作者Paul Jurczak
相关产品推荐
相关产品推荐

