Penso che sia meglio chiamare join()
sui tuoi fili quando ti aspetti che muoiano. Mi sono preso la libertà di far terminare la modifica dei tuoi loop (puoi aggiungere anche qualsiasi esigenza di pulizia richiesta). La variabile die
viene controllato ad ogni passaggio e quando è True
, il programma si chiude.
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 e i segnali sono visti solo dal processo (cioè il thread principale)... Dai un'occhiata a Ctrl-c cioè KeyboardInterrupt per terminare i thread in python
Ctrl +C termina il thread principale, ma poiché i tuoi thread non sono in modalità demone, continuano a funzionare e ciò mantiene vivo il processo. Possiamo renderli demoni:
f = FirstThread()
f.daemon = True
f.start()
s = SecondThread()
s.daemon = True
s.start()
Ma poi c'è un altro problema:una volta che il thread principale ha avviato i tuoi thread, non c'è nient'altro da fare. Quindi esce e i thread vengono distrutti all'istante. Quindi manteniamo vivo il thread principale:
import time
while True:
time.sleep(1)
Ora continuerà a stampare "primo" e "secondo" finché non premi Ctrl +C .
Modifica: come hanno sottolineato i commentatori, i thread del demone potrebbero non avere la possibilità di ripulire cose come i file temporanei. Se ne hai bisogno, prendi il KeyboardInterrupt
sul thread principale e coordinare la pulizia e l'arresto. Ma in molti casi, lasciare che i thread daemon muoiano improvvisamente è probabilmente sufficiente.
Una versione migliorata della risposta di @Thomas K:
- Definizione di una funzione assistente
is_any_thread_alive()
secondo questo concetto, che può terminare ilmain()
automaticamente.
Esempi di codici:
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)