Je teste le thread Python avec le script suivant:
import threading
class FirstThread (threading.Thread):
def run (self):
while True:
print 'first'
class SecondThread (threading.Thread):
def run (self):
while True:
print 'second'
FirstThread().start()
SecondThread().start()
Cela fonctionne en Python 2.7 sur Kubuntu 11.10. Ctrl+ Cne le tuera pas. J'ai également essayé d'ajouter un gestionnaire pour les signaux système, mais cela n'a pas aidé:
import signal
import sys
def signal_handler(signal, frame):
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
Pour tuer le processus, je le tue par PID après avoir envoyé le programme en arrière-plan avec Ctrl+ Z, ce qui n'est pas ignoré. Pourquoi Ctrl+ Cest-il ignoré si constamment? Comment puis-je résoudre ça?
Réponses:
Ctrl+ Ctermine le thread principal, mais comme vos threads ne sont pas en mode démon, ils continuent de fonctionner, ce qui maintient le processus en vie. Nous pouvons en faire des démons:
Mais il y a un autre problème: une fois que le thread principal a démarré vos threads, il n'y a rien d'autre à faire. Alors ça sort, et les fils sont détruits instantanément. Alors gardons le fil principal en vie:
Maintenant, il continuera à imprimer «premier» et «deuxième» jusqu'à ce que vous appuyiez sur Ctrl+ C.
Edit: comme les commentateurs l'ont souligné, les threads du démon peuvent ne pas avoir la possibilité de nettoyer des choses comme les fichiers temporaires. Si vous en avez besoin, attrapez le
KeyboardInterrupt
sur le thread principal et demandez -lui de coordonner le nettoyage et l'arrêt. Mais dans de nombreux cas, laisser les threads démons mourir soudainement est probablement suffisant.la source
tempfile.TemporaryFile()
peuvent être laissés sur le disque, par exemple.daemon=True
àThread.__init__
KeyboardInterrupt et les signaux ne sont vus que par le processus (c'est-à-dire le thread principal) ... Jetez un œil à Ctrl-c ie KeyboardInterrupt pour tuer les threads en python
la source
Je pense qu'il est préférable d'appeler join () sur vos threads lorsque vous vous attendez à ce qu'ils meurent. J'ai pris une certaine liberté avec votre code pour que les boucles se terminent (vous pouvez également y ajouter tous les besoins de nettoyage nécessaires). La variable die est vérifiée pour la vérité à chaque passage et quand il est vrai, le programme se termine.
la source
while True
est idiot, vous devriezjoin
directement - et cette fonction surchargée est assez discutable. Peut-êtredef join(self, force=False): if force: self.die = True
que celajoin()
ne change pas en lesjoin(force=True)
tue. Mais même dans ce cas, mieux vaut informer les deux threads avant de rejoindre l'un ou l'autre.Une version améliorée de la réponse de @Thomas K:
is_any_thread_alive()
de cet essentiel , qui peut terminermain()
automatiquement le.Exemples de codes:
la source