Se ho un thread in un ciclo infinito, c'è un modo per terminarlo quando termina il programma principale (ad esempio, quando premo Ctrl+ C)?
Risposte:
Controlla questa domanda. La risposta corretta ha un'ottima spiegazione su come terminare i thread nel modo giusto: esiste un modo per uccidere un thread in Python?
Per fermare il thread al segnale di interruzione della tastiera (ctrl + c) puoi catturare l'eccezione "KeyboardInterrupt" e ripulire prima di uscire. Come questo:
try:
start_thread()
except (KeyboardInterrupt, SystemExit):
cleanup_stop_thread()
sys.exit()
In questo modo puoi controllare cosa fare ogni volta che il programma viene interrotto bruscamente.
Puoi anche utilizzare il modulo di segnale integrato che ti consente di configurare i gestori di segnali (nel tuo caso specifico il segnale SIGINT): http://docs.python.org/library/signal.html
cleanup_stop_thread()
una funzione globale che posso usare? o dovrei aver bisogno di implementarlo?
Se crei dei thread daemon dei tuoi thread di lavoro, moriranno quando tutti i tuoi thread non daemon (ad esempio il thread principale) saranno terminati.
http://docs.python.org/library/threading.html#threading.Thread.daemon
isDaemon()
è False, impostalo True con setDaemon(True)
.
isDaemon()
e setDaemon()
sono vecchi getter / setter (come da documento collegato sopra), basta usare daemon=True
inthreading.Thread()
Prova ad abilitare il thread secondario come thread daemon.
Consigliato:
from threading import Thread
t = Thread(target=<your-method>)
t.daemon = True # This thread dies when main thread (only non-daemon thread) exits.
t.start()
In linea:
t = Thread(target=<your-method>, daemon=True).start()
Vecchia API:
t.setDaemon(True)
t.start()
Quando il thread principale termina ("cioè quando premo Ctrl+ C"), anche gli altri thread verranno interrotti dalle istruzioni precedenti.
Usa il modulo atexit della libreria standard di Python per registrare le funzioni di "terminazione" che vengono chiamate (sul thread principale) su qualsiasi terminazione ragionevolmente "pulita" del thread principale, inclusa un'eccezione non rilevata come KeyboardInterrupt
. Tali funzioni di terminazione possono (sebbene inevitabilmente nel thread principale!) Chiamare qualsiasi stop
funzione richiesta; insieme alla possibilità di impostare un thread come daemon
, che ti dà gli strumenti per progettare correttamente le funzionalità di sistema di cui hai bisogno.
atexit.register()
chiamate posticipate nei moduli Python, facendo sì che la vostra procedura di terminazione venga eseguita dopo multiprocessing
quella di. Mi imbatto in questo problema che tratta Queue
e daemon
thread: "Errore EOF" all'uscita del programma utilizzando Queue e Thread multiprocessing .
atexit
gestori non vengono chiamati quando i thread non daemon sono attivi e il thread principale esce. Vedere Script bloccato all'uscita quando si usa atexit per terminare i thread .
Se generi un filo in questo modo - myThread = Thread(target = function)
- e poi fallo myThread.start(); myThread.join()
. Quando viene avviato CTRL-C, il thread principale non si chiude perché è in attesa di quella myThread.join()
chiamata di blocco . Per risolvere questo problema, è sufficiente inserire un timeout nella chiamata .join (). Il timeout può essere lungo quanto desideri. Se vuoi che attenda indefinitamente, metti un timeout molto lungo, come 99999. È anche una buona pratica farlo in myThread.daemon = True
modo che tutti i thread escano quando il thread principale (non daemon) esce.
myThread.daemon = True
è una meravigliosa soluzione a questo problema.
.daemon=True
non è una soluzione solida. Controlla questo thread per una spiegazione: stackoverflow.com/a/20598791/5562492
I thread del demone vengono uccisi in modo sgraziato, quindi le istruzioni del finalizzatore non vengono eseguite. Una possibile soluzione è controllare se il thread principale è vivo anziché il ciclo infinito.
Ad esempio per Python 3:
while threading.main_thread().isAlive():
do.you.subthread.thing()
gracefully.close.the.thread()
Vedere Verificare se il thread principale è ancora attivo da un altro thread .