Closed rockswang closed 2 years ago
可以尝试一下在调用 multiprocessing.freeze_support()
前设置一下 sys.frozen
:
if not hasattr(sys, 'frozen'):
sys.frozen = True
multiprocessing.freeze_support()
PyInstaller 的 bootloader 里会帮你设置这个值,因此你只需要调用 freeze_support 就可以了:
https://pyinstaller.org/en/v3.3.1/runtime-information.html
The PyInstaller bootloader adds the name frozen to the sys module.
https://github.com/python/cpython/blob/main/Lib/multiprocessing/context.py
def freeze_support(self):
'''Check whether this is a fake forked process in a frozen executable.
If so then run code specified by commandline and exit.
'''
if sys.platform == 'win32' and getattr(sys, 'frozen', False):
from .spawn import freeze_support
freeze_support()
所以,没设置 sys.frozen
的话,multiprocessing.freeze_support() 就不会起作用。
附一个复现该 Bug 的 case:
PyStand.int:
# vim: set ts=4 sw=4 tw=0 et ft=python :
import multiprocessing
import sys, os
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import myprocess
if __name__ == '__main__':
multiprocessing.freeze_support()
multiprocessing.Process(target=myprocess.say_hello, daemon=True).start()
app = QApplication([])
win = QWidget()
win.setWindowTitle('PyStand')
layout = QVBoxLayout()
label = QLabel('Hello, World !!')
label.setAlignment(Qt.AlignCenter)
layout.addWidget(label)
btn = QPushButton(text = 'PUSH ME')
layout.addWidget(btn)
win.setLayout(layout)
win.resize(400, 300)
btn.clicked.connect(lambda : [
print('exit'),
win.close(),
])
win.show()
app.exec_()
myprocess.py:
def say_hello():
print('Hello, world!')
感谢支持!问题已经修复!
入口代码如下,开头会先启动一个后台进程。 python 直接执行正常,通过PyStand.exe 启动,就会不断启动Qt窗口,直到内存耗尽为止。 PyInstaller也有类似问题,按照PyInstaller的方案,加上了freeze_support(),但是问题依旧。 是否需要在PyStand.exe的主程序里添加此调用?