Spiegazione dei thread daemon


237

Nella documentazione di Python dice:

Un thread può essere contrassegnato come "thread demone". Il significato di questo flag è che l'intero programma Python si chiude quando rimangono solo thread daemon. Il valore iniziale viene ereditato dal thread di creazione.

Qualcuno ha una spiegazione più chiara di ciò che ciò significhi o un esempio pratico che mostri dove vorresti impostare le discussioni daemonic?

Chiariscimi: quindi l'unica situazione in cui non imposteresti i thread daemonic, è quando vuoi che continuino a funzionare dopo che il thread principale è uscito?

Risposte:


448

Alcuni thread eseguono attività in background, come l'invio di pacchetti keepalive o l'esecuzione di garbage collection periodiche o altro. Questi sono utili solo quando il programma principale è in esecuzione ed è possibile eliminarli una volta terminati gli altri thread, non daemon.

Senza thread demone, dovresti tenerne traccia e dire loro di uscire prima che il tuo programma possa chiudersi completamente. Impostandoli come thread daemon, puoi lasciarli correre e dimenticarli e quando il tuo programma si chiude, tutti i thread daemon vengono uccisi automaticamente.


1
Quindi se ho un thread figlio che sta eseguendo un'operazione di scrittura di file impostata su non-deamon, significa che devo farlo uscire esplicitamente?
Ciasto piekarz,

8
@san Cosa fa il tuo thread dello scrittore dopo aver finito di scrivere? Torna appena? Se è così, è sufficiente. I thread daemon sono generalmente per cose che girano in un ciclo e non si chiudono da soli.
Chris Jester-Young,

Non fa nulla, né ritorna, il suo unico scopo di eseguire un'operazione di scrittura di file
Ciasto piekarz,

2
@san Se cade dalla parte inferiore della funzione thread, restituisce implicitamente.
Chris Jester-Young,

In Nonequesto caso restituisce , ma non importa, il valore restituito non viene utilizzato.
Chris Jester-Young,

30

Supponiamo che tu stia creando una sorta di widget per dashboard. Come parte di questo, vuoi che mostri il conteggio dei messaggi non letti nella tua casella di posta elettronica. Quindi fai un piccolo thread che:

  1. Connettiti al server di posta e chiedi quanti messaggi non letti hai.
  2. Segnala la GUI con il conteggio aggiornato.
  3. Dormi per un po '.

Quando il tuo widget si avvia, creerebbe questo thread, lo designerebbe un demone e lo avvierebbe. Perché è un demone, non devi pensarci; quando il widget esce, il thread si interromperà automaticamente.


18

Altri poster hanno fornito alcuni esempi di situazioni in cui useresti thread demone. La mia raccomandazione, tuttavia, non è mai di usarli.

Non è perché non sono utili, ma perché ci sono alcuni effetti collaterali negativi che puoi sperimentare se li usi. I thread daemon possono ancora essere eseguiti dopo che il runtime di Python inizia a distruggere le cose nel thread principale, causando alcune eccezioni piuttosto bizzarre.

Maggiori informazioni qui:

https://joeshaw.org/python-daemon-threads-considered-harmful/

https://mail.python.org/pipermail/python-list/2005-February/343697.html

A rigor di termini non ne hai mai bisogno, in alcuni casi semplifica l'implementazione.


Ancora questo problema con Python 3? Non ci sono informazioni chiare su queste "strane eccezioni" nella documentazione.
kheraud,

5
Dal post del blog di Joe: "Aggiornamento giugno 2015: questo è il bug di Python del 1856. È stato corretto in Python 3.2.1 e 3.3, ma la correzione non è mai stata riportata a 2.x. (Un tentativo di eseguire il backport nel ramo 2.7 ha causato un altro bug ed è stato abbandonato.) I thread dei demoni potrebbero essere ok in Python> = 3.2.1, ma sicuramente non lo sono nelle versioni precedenti. "
clacke,

Vorrei condividere qui la mia esperienza: ho avuto una funzione generata come Thread più volte. Al suo interno, avevo un'istanza di Python logginge mi aspettavo che, dopo aver terminato il thread, tutti gli oggetti (descrittori di file per ogni thread / funzione) sarebbero stati distrutti. Alla fine del mio programma, ho visto molti output simili IOError: [Errno 24] Too many open files:. Con lsof -p pid_of_program, ho scoperto che gli FD erano aperti, anche se il Thread / Funzioni ha terminato il loro lavoro. Soluzione? Rimozione del gestore log alla fine della funzione. Quindi le daemonicdiscussioni, sono inaffidabili ...
Ivanleoncz,

17

Un modo più semplice di pensarci, forse: quando ritorna principale, il tuo processo non si chiuderà se ci sono ancora thread non daemon.

Un piccolo consiglio: l'arresto pulito è facile da sbagliare quando sono coinvolti thread e sincronizzazione - se puoi evitarlo, fallo. Usa thread demone quando possibile.


13

Chris ha già spiegato quali sono i thread dei demoni, quindi parliamo dell'uso pratico. Molte implementazioni di pool di thread utilizzano thread daemon per i task task. I lavoratori sono thread che eseguono attività dalla coda delle attività.

Il lavoratore deve continuare ad attendere le attività nella coda delle attività a tempo indeterminato poiché non sa quando verrà visualizzata la nuova attività. Il thread che assegna attività (ad esempio thread principale) sa solo quando le attività sono terminate. Il thread principale attende nella coda delle attività di svuotarsi e quindi esce. Se i lavoratori sono thread utente, ovvero non daemon, il programma non verrà chiuso. Continuerà ad aspettare questi lavoratori a tempo indeterminato, anche se i lavoratori non stanno facendo nulla di utile. Segna i thread del demone worker e il thread principale si occuperà di ucciderli non appena avrà finito di gestire le attività.


4
Stai attento! Se un programma invia un'attività importante (ad esempio, aggiorna un file "in background") a una coda di attività daemon, c'è il rischio che il programma possa terminare prima di eseguire l'attività, o peggio, nel mezzo dell'aggiornamento di quel file.
Solomon Slow,

10

Citando Chris: "... quando il tuo programma si chiude, tutti i thread del demone vengono uccisi automaticamente." Penso che riassuma. Dovresti stare attento quando li usi perché si interrompono bruscamente quando il programma principale viene eseguito fino al completamento.


4

Quando il secondo thread non è Daemon, il thread principale principale dell'applicazione non può essere chiuso perché i suoi criteri di uscita sono collegati all'uscita anche dei thread non Daemon. I thread non possono essere uccisi forzatamente in Python, quindi la tua app dovrà davvero attendere la chiusura dei thread non Daemon. Se questo comportamento non è quello che desideri, imposta il tuo secondo thread come demone in modo che non impedisca la chiusura dell'applicazione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.