Pyinstaller可执行文件保持打开

2022-03-24 00:00:00 python 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

我发现我正在使用的一个包--imultisVideoStream涉及threading。我想这就是观察from multiprocessing.semaphore_tracker的原因,尽管我没有显式地观察import multiprocessing

然后我遇到this post,建议添加multiprocessing.freeze_support()。它可以抑制GUI窗口保持复制,但是使用$ ps显示的后台进程仍然保持复制。问题尚未解决。


更新3(已找到问题但未修复)

调试代码一段时间后,发现这个无限循环的原因不是因为imultisVideoStream的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

相关文章