¿Qué es un proceso <defunct> y por qué no lo matan?

180

El navegador Chrome no respondía y traté de matarlo, pero en lugar de desaparecer, el proceso estaba <defunct>a la derecha y no me mataron:

ingrese la descripción de la imagen aquí

¿Qué es <defunct>para un proceso y por qué no lo matan?

Eduard Florinescu
fuente
3
La respuesta aceptada menciona que " kill -9 PIDno funciona". Es parcialmente cierto: en realidad, NO matar funcionará. Además, -9 debe usarse como último recurso. El 99% de las veces, una eliminación predeterminada del proceso principal la eliminará Y cosechará todos los elementos secundarios. Un "asesinato predeterminado" es un SIGTERM (-15). Animo a los fanáticos del -9 (SIGKILL) a leer stackoverflow.com/questions/690415/…
Mike S

Respuestas:

172

De su salida vemos un "difunto", lo que significa que el proceso ha completado su tarea o ha sido dañado o eliminado, pero sus procesos secundarios todavía se están ejecutando o estos procesos primarios están monitoreando su proceso secundario. Para matar este tipo de proceso, kill -9 PID no funciona. Puede intentar matarlos con este comando, pero lo mostrará una y otra vez.

Determine cuál es el proceso principal de este proceso difunto y elimínelo. Para saber esto, ejecute el 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>

Luego kill -9 637 27872, verifique que el proceso desaparecido haya pasado ps -ef | grep defunct.

Paddington
fuente
13
no puedes matar el proceso "difunto". Solo puede acelerar la eliminación de su entrada en una tabla de proceso al matar a su padre.
jfs
57
¿Qué pasa si el ppid es 1( init)? ¿Y si tendré que esperar?
Luc
77
para automatizar la matanza, se puede hacer esto, también (puede que tenga que cambiar la cual bytes que está cortando desde la salida):ps -ef | grep defunct | grep -v grep | cut -b8-20 | xargs kill -9
Warren
3
@warren Gracias. También puede hacer que sea un poco más corto y (imo) más simple al no hacer un segundo grep. Simplemente cambie el primer grep a grep [d]efuncto similar y no coincidirá.
Thor84no
44
@warren, no puedes matar un proceso difunto, incluso con un SIGKILL. Además, estás usando kill -9 de manera bastante indiscriminada. Ver stackoverflow.com/questions/690415/… . Si quieres matar a los niños difuntos, puede probar: parents_of_dead_kids=$(ps -ef | grep [d]efunct | awk '{print $3}' | sort | uniq | egrep -v '^1$'); echo "$parents_of_dead_kids" | xargs kill. Vuelva a ejecutar el script después de 30 segundos más o menos, con el kill -9si lo desea. (Tenga en cuenta que específicamente rechazo el asesinato de Init)
Mike S
60

La página del manual ps (1) dice :

Los procesos marcados <defunct>son procesos muertos (los llamados "zombis" ) que permanecen porque su padre no los ha destruido correctamente. Estos procesos serán destruidos init(8)si el proceso padre sale.

No puedes matarlo porque ya está muerto. Lo único que queda es una entrada en la tabla de proceso :

En los sistemas operativos de computadora Unix y similares a Unix, un proceso zombie o un proceso difunto es un proceso que ha completado la ejecución pero que aún tiene una entrada en la tabla de procesos. Esta entrada aún es necesaria para permitir que el proceso principal lea el estado de salida de su hijo.

No hay ningún daño en permitir que tales procesos sean a menos que haya muchos de ellos. Zombie finalmente es cosechado por su padre (llamando wait(2)). Si el padre original no lo ha cosechado antes de su propia salida, initprocess ( pid == 1) lo hace en algún momento posterior. Zombie Process es solo:

Un proceso que ha finalizado y que se elimina cuando su estado de salida se ha informado a otro proceso que está esperando que ese proceso finalice.

jfs
fuente
1

Gracias Mike S. Tomamos tu línea y escribimos un script que eliminará los procesos difuntos cuyo padre está en.telnetd. No queríamos que matara ningún proceso padre, solo telnetd que sabemos que está causando un problema y lo ejecutaremos varias veces para matar varios si es necesario.

# 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
David Brazzeal
fuente
1

ampliando la respuesta de Paddington ...

De su salida vemos un difunto , lo que significa que este proceso secundario ha completado su tarea o ha sido dañado o eliminado. Su proceso padre todavía se está ejecutando y no se ha dado cuenta de su hijo muerto.

kill -9 PID no funcionará (ya está muerto).

Para determinar el padre de este proceso hijo, ejecute este comando:

ps -ef | grep defunct

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

Vea quién es el padre: ps ax | grep 27872

Si quieres puedes matar al padre, y el difunto desaparecerá. kill -9 27872

vea la respuesta de JF Sebastian para un razonamiento más técnico.

kevinf
fuente
1

Agregando a la respuesta de @ Paddington, agregué esta función a mi bashrc para una verificación rápida:

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
}

Produce algo como:

Niños:
UID PID PPID C TIEMPO TTY TIEMPO CMD
usuario 25707 25697 0 feb26 pts / 0 00:00:00 [sh] 
usuario 30381 29915 0 11:46 pts / 7 00:00:00 grep difunto
------------------------------
Padres:
25697 pts / 0 00:00:00 npm
agregado 1166877
fuente