Pyinstaller可执行文件保持打开
问题描述
背景
我正在研究this link后面的人脸识别,我想使用Python构建一个独立的应用程序。我的main.py
脚本如下所示。
# main.py
# Import packages and other scripts
import tkinter as tk
...
# Some functions
def initialization():
# OpenCV and sklearn are used here
...
def registration():
# OpenCV, and sklearn are used here
...
def face_recognition():
# OpenCV and sklearn are used here
...
# Start the Tkinter GUI
window = tk.Tk()
# Initialize the face recognition model
initialization()
# Input name for registration
tk.Label(window, text = "Name").grid(...)
entry1 = tk.Entry(window)
entry1.grid(row=0, column=1)
# When the button is clicked, different command is executed
tk.Button(window, text='Registration', command=registeration).grid(...)
tk.Button(window, text='Face Recognition', command=face_recognition).grid(...)
window.mainloop()
使用python解释器运行脚本(python main.py
),一切正常。
问题
我使用Pyinstaller通过以下命令将脚本转换为单个exe:
pyinstaller --onefile
--windowed
--hidden-import sklearn.neighbors.typedefs
main.py
然后,我生成了两个可执行文件。第一个在dist/main
中,第二个在dist/main.app/Contents/MacOS/main
中
运行exe时,exe自身保持重复。我显示正在运行的进程并找到此结果
$ ps
PID TTY TIME CMD
... ... ... /path/to/main -B -s -S -E -c from multiprocessing.semaphore_tracker import main:main(8)
... ... ... /path/to/main -B -s -S -E -c from multiprocessing.semaphore_tracker import main:main(8)
... ... ... /path/to/main -B -s -S -E -c from multiprocessing.semaphore_tracker import main:main(7)
... ... ... /path/to/main -B -s -S -E -c from multiprocessing.semaphore_tracker import main:main(7)
... ... ... /path/to/main -B -s -S -E -c from multiprocessing.semaphore_tracker import main:main(8)
我不知道exe会发生什么情况,因为我没有在脚本中导入多处理包。你知道怎么解决这个问题吗?谢谢
更新%1
我在使用Pyinstaller
时添加了一个--log-level ERROR
,并给出了此结果。不确定是否与我的问题有关。
Traceback (most recent call last):
File "<string>", line 2, in <module>
ModuleNotFoundError: No module named 'Crypto.Math'
174598 INFO: MKL libraries found when importing numpy. Adding MKL to binaries
176282 ERROR: Can not find path ./libtbb.dylib (needed by /Users/user/anaconda3/lib/libmkl_tbb_thread.dylib)
更新2
我发现我正在使用的一个包--imultis
VideoStream涉及threading
。我想这就是观察from multiprocessing.semaphore_tracker
的原因,尽管我没有显式地观察import multiprocessing
。
然后我遇到this post,建议添加multiprocessing.freeze_support()
。它可以抑制GUI窗口保持复制,但是使用$ ps
显示的后台进程仍然保持复制。问题尚未解决。
更新3(已找到问题但未修复)
调试代码一段时间后,发现这个无限循环的原因不是因为imultis
VideoStream的threading
(我另外写了一个脚本来测试imultis
,完全正常)。但问题来自进口sklearn
!此问题已在this link中的GitHub中报告。
此GitHub链接还建议包含multiprocessing.freeze_support()
。此外,其中一个响应建议在调用multiprocessing.freeze_support()
之后导入sklearn
。我用一个简单的脚本进行了尝试,但问题仍然存在。
结论:sklearn
导致可执行文件持续打开。但我不知道为什么会这样,我也不知道如何解决。任何帮助都将不胜感激。谢谢。
解决方案
此答案很好地解释了为什么会发生这种情况:https://stackoverflow.com/a/55382641/109525
在启动程序之前先尝试设置此设置:
export JOBLIB_MULTIPROCESSING=0
如果它可以工作,您可以向程序添加一个运行时挂钩,以自动设置环境变量。请参阅:https://pythonhosted.org/PyInstaller/when-things-go-wrong.html#changing-runtime-behavior
相关文章