5
votes

L'exécutable Pyinstaller continue de s'ouvrir

Contexte

Je travaille sur la reconnaissance faciale après ceci lien et je voudrais créer une application autonome en utilisant Python. Mon script main.py ressemble à ce qui suit.

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)

Utilisation de python interpréter pour exécuter le script ( python main.py code >), tout fonctionne bien.


Problème

J'utilise Pyinstaller pour convertir les scripts en un seul exe avec cette commande: p >

$ 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)

Ensuite, j'ai généré deux exe. Le premier est dans dist / main et le second est dans dist/main.app/Contents/MacOS/main

Lors de l'exécution de l'exe , l'exe se duplique. J'affiche le processus en cours et j'ai trouvé ce résultat

pyinstaller --onefile \
            --windowed \
            --hidden-import sklearn.neighbors.typedefs \
            main.py

Je n'ai aucune idée de ce qui arrive à l'exe puisque je n'importe pas de paquets multiprocesseurs dans mes scripts. Une idée comment résoudre ce problème? Merci


Mise à jour 1

J'ai ajouté un --log-level ERROR lors de l'utilisation de Pyinstaller et donne ce résultat. Je ne sais pas si cela est lié à mon problème.

# 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()

Mise à jour 2

J'ai découvert que l'un des les packages que j'utilise - imultis VideoStream implique threading . Je suppose que c'est la raison pour laquelle on observe à partir de multiprocessing.semaphore_tracker comme indiqué ci-dessus, même si je n’importe pas le multiprocesseur explicitement.

ce message , suggérant d'ajouter multiprocessing.freeze_support () . Il peut empêcher la fenêtre GUI de continuer à se dupliquer, mais les processus d'arrière-plan comme indiqué à l'aide de $ ps continuent de se dupliquer. Le problème n'est pas encore résolu.


Mise à jour 3 (problème localisé mais non résolu)

Après avoir débogué le code pendant un certain temps, il il s'avère que les causes de cette boucle infinie ne sont PAS dues au threading de imultis VideoStream (j'écris un autre script pour tester imultis et c'est complètement OK). Mais le problème vient de l'importation de sklearn !!! Ce problème a été signalé dans GitHub dans ce lien .

Ce lien GitHub suggère également d'inclure multiprocessing.freeze_support () . De plus, l'une des réponses suggère d'importer sklearn après l'appel de multiprocessing.freeze_support () . Je l'essaie avec un script simple mais le problème est toujours là.

Conclusion : sklearn provoque l'ouverture continue de l'exécutable. Mais je n'ai aucune idée de pourquoi c'est le cas, et je ne sais pas comment le résoudre. Toute aide serait appréciée. Merci.


1 commentaires

peut-être que vous devez utiliser waitkey dans votre main.py pour attendre que certaines clés détruisent votre fenêtre. Et utilisez également destroyAllWindows .


4 Réponses :


0
votes

J'ai rencontré le même problème. Scikit-learn fournit une solution de contournement.

https://scikit-learn.org/stable/faq.html#why-do-i-sometime-get-a-crash- freeze-with-n-jobs-1-under-osx-or-linux

J'ai ajouté les codes ci-dessous au début de mon script et corrigé mon problème:

import multiprocessing
multiprocessing.set_start_method('forkserver', force=True)
multiprocessing.freeze_support()

J'espère que cela peut également résoudre le vôtre.


1 commentaires

Merci. maintenant, le programme ne fourche pas les processus à l'infini Mais quand même, quand je vérifie le processus d'arrière-plan, il affiche / chemin / vers / main -B -s -S -E -c de multiprocessing.semaphore_tracker import main: main (7) . Une idée pourquoi il existe de tels processus?



0
votes

Ce correctif ne fonctionne pas sous macOS - le problème persiste si vous bloquez une application avec PyInstaller qui appelle sklearn. J'utilise Python 3.7.2 avec PyInstaller 3.4 et PyQT5 5.12, sur macOS Mojave 10.14.3.


0 commentaires

1
votes

Cette réponse explique bien pourquoi cela se produit: https://stackoverflow.com/a/55382641/109525

Essayez d'abord de définir ceci avant de démarrer votre programme:

export JOBLIB_MULTIPROCESSING=0

Si cela fonctionne, vous pouvez ajouter un hook d'exécution à votre programme pour définir automatiquement la variable d'environnement. Voir: https://pythonhosted.org/PyInstaller/ quand-les-choses-vont-mal.html # changer-comportement-d'exécution


0 commentaires

0
votes

Commencer mon point d'entrée principal avec:

from multiprocessing import freeze_support
freeze_support()

A fonctionné pour moi!


0 commentaires