我刚刚在我的程序中发现了一个与使用Python的多处理模块相关的奇怪错误。当我从我的机器上的源程序运行程序时,一切正常。但是我一直在使用pyinstaller将它构建成可执行文件,并且由于某种原因,当我运行从我的代码构建的可执行文件时,多处理的行为会发生巨大变化。具体来说,当我尝试运行代码的多处理部分时,而不是按照它应该执行的操作,会弹出一个似乎是我程序主窗口的副本,每个进程一个。更糟糕的是,如果他们手动关闭,他们会重新打开,大概是因为他们是多处理的一部分。没有打印错误消息,一旦创建,所有窗口就坐在那里什么都不做。可能会发生什么导致这种情况?
答案 0 :(得分:9)
在Windows上,multiprocessing
尝试通过启动可执行文件的新实例来模拟Unix fork()
系统调用,并在其中执行其子进程例程(multiprocessing.forking.main()
)。使用标准Python解释器(python.exe
),multiprocessing
可以传递-c
参数来运行自定义代码。但是,对于自定义可执行文件,这是不可能的,因为可执行文件很可能不支持与python.exe
相同的命令行选项。
freeze_support()
函数通过显式执行子进程例程来回避此问题,并通过调用sys.exit()
来终止解释器。如果您忘记调用freeze_support()
,则新进程不知道它是子进程并运行主应用程序逻辑。在您的情况下,这将弹出另一个主GUI窗口。
由于从新创建的进程开始另一个子进程将导致无限递归,multiprocessing
会尝试通过检查sys.frozen
属性来阻止此情况,并在RuntimeError
时引发freeze_support()
没被叫。在您的情况下,似乎需要用户交互来生成进程,因此没有无限递归而且没有RuntimeError
。
按照惯例,sys.frozen
仅设置为由py2exe
或PyInstaller创建的自动生成的可执行文件。当需要将Python嵌入到应支持Windows下的多处理的自定义可执行文件中时,理解此逻辑并将sys.frozen
设置为True
非常重要。