Che cos'è un processo <defunct> e perché non viene ucciso?


180

Il browser Chrome non era reattivo e ho cercato di ucciderlo, ma invece di scomparire il processo aveva <defunct>alla sua destra e non mi ha ucciso:

inserisci qui la descrizione dell'immagine

Cosa serve <defunct>per un processo e perché non viene ucciso?


3
La risposta accettata menziona che " kill -9 PIDnon funziona". È parzialmente vero: in realtà, nessuna uccisione funzionerà. Inoltre, -9 dovrebbe essere usato come ultima risorsa. Il 99% delle volte un'uccisione predefinita del processo genitore lo ucciderà E raccoglierà tutti i bambini. Un "kill predefinito" è un SIGTERM (-15). Incoraggio i fan del -9 (SIGKILL) a leggere stackoverflow.com/questions/690415/…
Mike S,

Risposte:


172

Dal tuo output vediamo un "defunct", il che significa che il processo ha completato il suo compito o è stato corrotto o ucciso, ma i suoi processi figlio sono ancora in esecuzione o questi processi principali stanno monitorando il suo processo figlio. Per uccidere questo tipo di processo, uccidere -9 PID non funziona. Puoi provare a ucciderli con questo comando ma lo mostrerà ancora e ancora.

Determina qual è il processo genitore di questo processo defunto e uccidilo. Per sapere questo eseguire il comando:

ps -ef | grep defunct

UID          PID     PPID       C    STIME      TTY          TIME              CMD
1000       637      27872      0   Oct12      ?        00:00:04 [chrome] <defunct>
1000      1808      1777       0    Oct04     ?        00:00:00 [zeitgeist-datah] <defunct>

Quindi kill -9 637 27872, verifica che il processo defunto sia passato ps -ef | grep defunct.


13
non puoi uccidere il processo "defunto". Puoi solo accelerare la cancellazione della sua voce in una tabella di processo uccidendo il suo genitore.
jfs,

57
E se il ppid è 1( init)? Supponiamo che dovrò solo aspettare?
Luc,

7
per automatizzare l'uccisione, puoi farlo anche tu (potrebbe essere necessario cambiare quali byte stai tagliando dall'output):ps -ef | grep defunct | grep -v grep | cut -b8-20 | xargs kill -9
warren

3
@warren Grazie. Puoi anche renderlo leggermente più breve e (imo) più semplice non facendo un secondo grep. Basta cambiare il primo grep in grep [d]efuncto simile e non corrisponderà a se stesso.
Thor84no,

4
@warren non puoi uccidere un processo defunto, anche con un SIGKILL. Inoltre, stai usando kill -9 piuttosto indiscriminatamente. Vedi stackoverflow.com/questions/690415/… . Se si vuole uccidere i bambini defunti, si potrebbe provare: parents_of_dead_kids=$(ps -ef | grep [d]efunct | awk '{print $3}' | sort | uniq | egrep -v '^1$'); echo "$parents_of_dead_kids" | xargs kill. Rieseguire la sceneggiatura dopo circa 30 secondi, con il kill -9se desiderato. (Nota che non ammetto specificamente l'uccisione di Init)
Mike S

60

La pagina del manuale ps (1) dice :

I processi contrassegnati <defunct>sono processi morti (i cosiddetti "zombi" ) che rimangono perché il loro genitore non li ha distrutti correttamente. Questi processi verranno distrutti init(8)se si esce dal processo padre.

Non puoi ucciderlo perché è già morto. L'unica cosa rimasta è una voce nella tabella dei processi :

Sui sistemi operativi per computer Unix e Unix, un processo zombie o un processo defunto è un processo che ha completato l'esecuzione ma ha ancora una voce nella tabella dei processi. Questa voce è ancora necessaria per consentire al processo genitore di leggere lo stato di uscita del figlio.

Non vi è alcun danno nel lasciare tali processi a meno che non ce ne siano molti. Alla fine lo zombi viene raccolto dal suo genitore (chiamando wait(2)). Se il genitore originale non lo ha raccolto prima della sua uscita, initprocess ( pid == 1) lo fa in un secondo momento. Zombie Process è solo:

Un processo che è terminato e che viene eliminato quando il suo stato di uscita è stato segnalato a un altro processo che è in attesa che il processo termini.


1

Grazie Mike S. Abbiamo preso la tua linea e scritto una sceneggiatura che ucciderà i processi defunti il ​​cui genitore è in.telnetd. Non volevamo che uccidesse alcun processo genitore, solo telnetd che sappiamo sta causando un problema e lo eseguiremo più volte per ucciderne di più se necessario.

# egrep -v '^1$ = Make sure the process is not the init process.
# awk '{print $3}' = Print the parent process.

first_parent_of_first_dead_kid=$(ps -ef | grep [d]efunct | awk '{print $3}' | head -n1 | egrep -v '^1$')
echo "$first_parent_of_first_dead_kid"

# If the first parent of the first dead kid is in.telnetd, then kill it.
if ps -ef | grep $first_parent_of_first_dead_kid | grep in.telnetd;then
        echo "We have a defunct process whose parent process is in.telnetd" | logger -t KILL-DEFUNCT-TELNET
        echo "killing $first_parent_of_first_dead_kid" | logger -t KILL-DEFUNCT-TELNET
        kill $first_parent_of_first_dead_kid 2>&1 | logger -t KILL-DEFUNCT-TELNET
fi

1

espandendo sulla risposta di Paddington ..

Dalla tua uscita vediamo un defunto , il che significa che questo processo figlio ha completato il suo compito o è stato corrotto o ucciso. Il processo padre è ancora in esecuzione e non ha notato il figlio morto.

kill -9 PID non funzionerà (già morto).

Per determinare il genitore di questo processo figlio, eseguire questo comando:

ps -ef | grep defunct

 UID  PID **PPID** C STIME TTY TIME     CMD
 1000 637  27872   0 Oct12 ?   00:00:04 [chrome] <defunct>

Vedi chi è il genitore: ps ax | grep 27872

Se vuoi puoi uccidere il genitore e il defunto andrà via. kill -9 27872

vedere la risposta di JF Sebastian per un ragionamento più tecnico.


1

Aggiungendo alla risposta di @ Paddington, ho aggiunto questa funzione al mio bashrc per un rapido controllo:

defunct(){
    echo "Children:"
    ps -ef | head -n1
    ps -ef | grep defunct
    echo "------------------------------"
    echo "Parents:"
    ppids="$(ps -ef | grep defunct | awk '{ print $3 }')"
    echo "$ppids" | while read ppid; do
        ps -A | grep "$ppid"
    done
}

Emette qualcosa del tipo:

Bambini:
UID PID PPID C STIME TTY TIME CMD
utente 25707 25697 0 febbraio 26 punti / 0 00:00:00 [sh] 
utente 30381 29915 0 11:46 pts / 7 00:00:00 grep defunct
------------------------------
genitori:
25697 punti / 0 00:00:00 npm
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.