问题描述
我使用 cx_Freeze 构建了一个可执行文件。我总是读到我需要包含 multiprocessing.freeze_support
以避免在任务管理器中运行的可执行文件的多个任务。但是如果我使用 multiprocessing 和 freeze_support,我仍然会在任务管理器中运行两个任务。
这是我名为 test_wibu.py
的示例 GUI:
import multiprocessing
from multiprocessing import freeze_support
import threading
import queue
import tkinter as tk
import psutil
import time
from tkinter.filedialog import *
sys._enablelegacywindowsfsencoding()
def worker(pqueue):
while True:
obj = pqueue.get()
obj.execute()
del obj
if __name__ == '__main__':
freeze_support()
q = queue.Queue(maxsize=0)
root = Tk()
print('Doing something to build the software interface')
time.sleep(3)
label = Label(root,text='Software',anchor=CENTER)
label.grid(column=0,row=0,sticky='nwse',padx=0,pady=0)
pqueue = multiprocessing.Queue()
pool = multiprocessing.Pool(1,worker,(pqueue,))
parent = psutil.Process()
q.put('stop')
root.mainloop()
还有我的 setup_wibu.py:
import os.path
from cx_Freeze import *
PYTHON_INSTALL_DIR = os.path.join(os.getenv('LOCALAPPDATA'),'Programs','Python','python36')
os.environ['TCL_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR,'tcl','tcl8.6')
os.environ['TK_LIBRARY'] = os.path.join(PYTHON_INSTALL_DIR,'tk8.6')
executables = [
Executable('test_wibu.py',base='win32gui',targetName='test.exe',)
]
options = {
'build_exe': {
'excludes': ['gtk','PyQt4','PyQt5','scipy.spatial.cKDTree','sqlite3','IPython'],'packages': [],'includes':['pkg_resources'],'include_files': [os.path.join(PYTHON_INSTALL_DIR,'DLLs','tk86t.dll'),os.path.join(PYTHON_INSTALL_DIR,'tcl86t.dll')]
},}
setup(
name='pest_wibu',version='1.0',executables=executables,options=options,)
如果我构建可执行文件并运行它,我会在任务管理器的“详细信息”中找到两个名为 test.exe
的任务。
这是正常行为吗?如何避免可执行文件创建多个任务?
解决方法
根据this excellent answer,multiprocessing.freeze_support()
调用的原因是
在 Windows 上缺少 fork()
(这并不完全正确)。因此,在 Windows 上,通过创建一个新进程来模拟 fork,在该进程中运行在 Linux 上正在子进程中运行的代码。
因此不会避免您的前提中所述的在任务管理器中运行的可执行文件的多个任务。
因此,您在任务管理器中观察到的行为可能是正常的,无法避免。