Python - Multiprocessing.processes从可执行文件运行时成为主进程的副本

时间:2011-08-15 16:35:56

标签: python multiprocessing

我刚刚在我的程序中发现了一个与使用Python的多处理模块相关的奇怪错误。当我从我的机器上的源程序运行程序时,一切正常。但是我一直在使用pyinstaller将它构建成可执行文件,并且由于某种原因,当我运行从我的代码构建的可执行文件时,多处理的行为会发生巨大变化。具体来说,当我尝试运行代码的多处理部分时,而不是按照它应该执行的操作,会弹出一个似乎是我程序主窗口的副本,每个进程一个。更糟糕的是,如果他们手动关闭,他们会重新打开,大概是因为他们是多处理的一部分。没有打印错误消息,一旦创建,所有窗口就坐在那里什么都不做。可能会发生什么导致这种情况?

1 个答案:

答案 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非常重要。