import multiprocessing as mp
class MainWindow(BaseWindow):
def __init__(self, app: QApplication, ui: Ui_MainWindow) -> None:
super(MainWindow, self).__init__(app, ui)
self.pool = mp.Pool(initializer=init_logging)
在这里 当我使用下面的脚本将其编译为 .exe 时,
self.pool = mp.Pool(initializer=init_logging)
部分会导致应用程序自我繁殖并最终粉碎窗口。
@echo off
pyinstaller --noconfirm --onefile --windowed --icon "epey.ico" --add-data "log_config.json;." --add-data "JSONFormatter.py;." --distpath ./dist "main.py"
del main.spec
pause
如果我用
python main.py
运行它,一切都很好。
def init_logging():
log_dir = Path("logs")
if not log_dir.exists():
log_dir.mkdir()
if getattr(sys, "frozen", False) and hasattr(sys, "_MEIPASS"):
config_file = Path(sys._MEIPASS) / "log_config.json" # type: ignore
else:
config_file = Path("log_config.json")
with open(config_file) as f:
config = json.load(f)
logging.config.dictConfig(config)
queue_handler = logging.getHandlerByName("queue_handler")
if queue_handler is not None:
queue_handler.listener.start() # type: ignore
atexit.register(queue_handler.listener.stop) # type: ignore
我虽然这可能会导致
self.pool = mp.Pool(initializer=init_logging)
中的问题,因为当我将程序编译为.exe时,它从临时文件(sys._MEIPASS)获取日志配置,但它不起作用。
好吧,经过一番研究。显然这是 Windows 特定的事情。在 Windows 上的多处理中,当生成一个新进程时,整个脚本将被重新执行(而不是像在 Unix 系统上那样被分叉),这会导致在我的例子中一遍又一遍地创建 PyQt 应用程序。为了解决这个问题,您需要像这样添加 mp.freeze_support() :
if __name__ == "__main__":
mp.freeze_support()
main()