Je pense qu'il est préférable d'appeler join()
sur vos fils quand vous vous attendez à ce qu'ils meurent. J'ai pris la liberté de modifier vos boucles pour qu'elles se terminent (vous pouvez également y ajouter tous les besoins de nettoyage nécessaires). La variable die
est vérifié à chaque passage et lorsqu'il est True
, le programme se termine.
import threading
import time
class MyThread (threading.Thread):
die = False
def __init__(self, name):
threading.Thread.__init__(self)
self.name = name
def run (self):
while not self.die:
time.sleep(1)
print (self.name)
def join(self):
self.die = True
super().join()
if __name__ == '__main__':
f = MyThread('first')
f.start()
s = MyThread('second')
s.start()
try:
while True:
time.sleep(2)
except KeyboardInterrupt:
f.join()
s.join()
KeyboardInterrupt et les signaux ne sont vus que par le processus (c'est-à-dire le thread principal) ... Jetez un œil à Ctrl-c c'est-à-dire KeyboardInterrupt pour tuer les threads en python
Ctrl +C termine 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 :
f = FirstThread()
f.daemon = True
f.start()
s = SecondThread()
s.daemon = True
s.start()
Mais alors 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. Donc, il sort et les threads sont détruits instantanément. Gardons donc le fil principal en vie :
import time
while True:
time.sleep(1)
Maintenant, il gardera l'impression 'first' et 'second' jusqu'à ce que vous appuyiez sur Ctrl +C .
Modifier : comme l'ont souligné les commentateurs, les threads démons peuvent ne pas avoir la possibilité de nettoyer des éléments tels que les fichiers temporaires. Si vous en avez besoin, attrapez le KeyboardInterrupt
sur le thread principal et faites-le coordonner le nettoyage et l'arrêt. Mais dans de nombreux cas, laisser les threads démons mourir soudainement est probablement suffisant.
Une version améliorée de la réponse de @Thomas K :
- Définir une fonction d'assistant
is_any_thread_alive()
selon cet essentiel, qui peut terminer lemain()
automatiquement.
Exemples de codes :
import threading
def job1():
...
def job2():
...
def is_any_thread_alive(threads):
return True in [t.is_alive() for t in threads]
if __name__ == "__main__":
...
t1 = threading.Thread(target=job1,daemon=True)
t2 = threading.Thread(target=job2,daemon=True)
t1.start()
t2.start()
while is_any_thread_alive([t1,t2]):
time.sleep(0)