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