PyQt6与multiprocessing结合编译为.exe后程序异常复制并崩溃求助
问题分析
PyInstaller单文件打包后,使用multiprocessing.Pool导致程序无限自我复制崩溃,核心原因是:
- Windows系统下multiprocessing默认采用
spawn启动模式,子进程会完整重新执行打包后的可执行文件 - 单文件打包的程序,子进程启动时没有正确的入口防护,导致子进程再次初始化Qt应用、创建进程池,形成无限递归启动新进程
解决方案
1. 给主脚本添加入口防护并调用freeze_support()
修改主脚本的结构,确保只有在主进程(__name__ == '__main__')时才初始化Qt应用和创建窗口,同时必须在创建进程池前调用multiprocessing.freeze_support():
import sys import multiprocessing as mp from PyQt6.QtWidgets import QApplication # 导入你的窗口类和UI类 from your_ui_module import Ui_MainWindow from your_window_module import MainWindow def main(): # 必须放在所有进程创建操作之前,处理PyInstaller打包后的子进程启动逻辑 mp.freeze_support() app = QApplication(sys.argv) ui = Ui_MainWindow() window = MainWindow(app, ui) window.show() sys.exit(app.exec()) # 只有主进程会执行这个分支,子进程启动时__name__不会是__main__ if __name__ == '__main__': main()
2. 确保进程池初始化逻辑不会被重复执行
你的MainWindow.__init__中创建进程池的代码,由于主窗口只在主进程的main()函数中初始化,子进程不会走到这一步,因此不会重复创建进程池。
3. 检查子进程初始化函数(init_logging)
如果保留init_logging作为进程池初始化函数,需要确保:
- 函数内不要包含任何Qt GUI相关操作(Qt不支持在子进程中创建GUI组件)
- 资源路径读取逻辑正确(你当前的
sys._MEIPASS处理是正确的)
4. 调整PyInstaller打包参数(可选)
如果上述步骤仍有问题,可以尝试在打包脚本中添加--noupx参数(避免UPX压缩导致的子进程启动问题):
@echo off pyinstaller --noconfirm --onefile --windowed --noupx --icon "epey.ico" --add-data "log_config.json;." --add-data "JSONFormatter.py;." --distpath ./dist "main.py" del main.spec pause
验证
修改后重新打包运行,程序只会启动一个主窗口,进程池创建的子进程不会重复初始化主程序,避免无限自我复制和崩溃。
内容的提问来源于stack exchange,提问作者1tsimple
相关产品推荐
相关产品推荐

