web-dev-qa-db-fra.com

python: comment terminer un thread à la fin du programme principal

Si j’ai un fil dans une boucle infinie, y at-il un moyen de le terminer lorsque le programme principal se termine (par exemple, lorsque j’appuie sur Ctrl+C)?

72
facha

Vérifiez cette question. La bonne réponse a une bonne explication sur la façon de terminer les threads de la bonne façon: Y a-t-il un moyen de tuer un thread en Python?

Pour arrêter le thread sur le signal d'interruption du clavier (ctrl + c), vous pouvez intercepter l'exception "KeyboardInterrupt" et le nettoyer avant de quitter. Comme ça:

try:
    start_thread()  
except (KeyboardInterrupt, SystemExit):
    cleanup_stop_thread()
    sys.exit()

De cette façon, vous pouvez contrôler quoi faire chaque fois que le programme est interrompu de manière abrupte.

Vous pouvez également utiliser le module de signal intégré qui vous permet de configurer les gestionnaires de signaux (dans votre cas, le signal SIGINT): http://docs.python.org/library/signal.html

42
rogeriopvl

Si vous créez des threads démon pour vos threads de travail, ils mourront lorsque tous vos threads autres que les démons (par exemple, le thread principal) se seront terminés.

http://docs.python.org/library/threading.html#threading.Thread.daemon

83
ʇsәɹoɈ

Utilisez le module atexit de la bibliothèque standard de Python pour enregistrer les fonctions "de terminaison" appelées (sur le thread principal) sur toute terminaison raisonnablement "propre" du thread principal, y compris une exception non interceptée telle que KeyboardInterrupt. De telles fonctions de terminaison peuvent (bien qu'inévitablement dans le thread principal!) Appeler n'importe quelle fonction stop dont vous avez besoin; avec la possibilité de définir un thread comme daemon, cela vous donne les outils pour concevoir correctement les fonctionnalités du système dont vous avez besoin.

12
Alex Martelli

Essayez d'activer le sous-fil en tant que daemon-thread.

Par exemple:

from threading import Thread

threaded = Thread(target=<your-method>)
threaded.daemon = True  # This thread dies when main thread (only non-daemon thread) exits.
threaded.start()

Ou (en ligne):

from threading import Thread

threaded = Thread(target=<your-method>, daemon=True).start()

Lorsque votre fil principal se termine ("par exemple, lorsque j'appuie sur Ctrl+C") que d'autres threads tue avec les instructions ci-dessus.

8
Benyamin Jafari

Si vous créez un thread comme celui-ci - myThread = Thread(target = function) - et faites ensuite myThread.start(); myThread.join(). Lorsque CTRL-C est lancé, le thread principal ne se ferme pas car il attend cet appel bloquant myThread.join(). Pour résoudre ce problème, il suffit de mettre un délai d'attente sur l'appel .join (). Le délai peut être aussi long que vous le souhaitez. Si vous voulez attendre indéfiniment, mettez simplement un délai très long, comme 99999. C'est également une bonne pratique de faire myThread.daemon = True afin que tous les threads se terminent lorsque le thread principal (non-démon) se ferme.

8
Milean

Les threads de démon sont tués de manière disgracieuse, de sorte que les instructions du finaliseur ne sont pas exécutées. Une solution possible est de vérifier si le thread principal est actif au lieu d'une boucle infinie.

Par exemple. pour Python 3:

while threading.main_thread().isAlive():
    do.you.subthread.thing()
gracefully.close.the.thread()

Voir Vérifiez si le thread principal est toujours actif depuis un autre thread .

0
umi