Respuesta corta: no es posible matar un proceso "zombie", porque ya está muerto. Pero sí es posible
Esto ocurre cuando un proceso finaliza su ejecución (termina), pero su padre (proceso que inició al proceso zombie) no está esperando por su finalización (no recibe el código de retorno). Un proceso "zombie" no existe como tal, ya no está en memoria y no utiliza CPU. Pero el núcleo del sistema operativo aún mantiene información acerca del mismo, el estado de salida o código de retorno, y está esperando que el proceso padre la reclame.
Entonces, un proceso "zombie" es una simple entrada en la tabla de procesos del núcleo del sistema operativo. Lo cual implica que no es posible matar un proceso "zombie", porque ya está muerto. Por más que se le envíen señales como kill -"hachazo en la cabeza", no va a desaparecer (digamos que no ocurre como en las series de zombies).
En este escenario hay dos alternativas: 1- el proceso padre finaliza y los procesos zombies son heredados por init, quien se encarga de recolectarlos y eliminarlos (reclamar su estado para que desaparezcan de la tabla de procesos del núcleo del sistema operativo); 2- Matar al proceso padre para forzar su desaparición.
La solución típica a este problema suele ser la segunda alternativa: matar al proceso padre para que desaparezcan los procesos zombies.
En general, los procesos zombies están asociados a malas prácticas de programación o falta de robustez de un programa. Cuando un proceso lanza procesos hijos, debe hacerse responsable por ellos, es decir, estar listo y esperar su eventual finalización, por más que no ellos no estén pensados para finalizar nunca.
De acuerdo al manual de ps en sistemas operativos GNU/Linux:
De acuerdo al manual de ps en sistemas FreeBSD:
Ejemplo de un caso real
Se trata de un servidor GNU/Linux corriendo un motor de bases de datos IBM Informix. Por causas anormales, una instancia de base de datos ha generado procesos zombies:
Para que desaparezcan estos procesos zombies es necesario matar a todos sus padres. Para ello es necesario conocer el PID (Process ID) de cada padre. Es posible determinar el PID del proceso padre de cada proceso utilizando el comando ps -eo pid,ppid. Por ejemplo, el PID del proceso padre del proceso cuyo PID es 9665 es 9664:
Así, es posible agregar la clave "command" y filtrar por "defunct":
Se observa que el padre para todos estos procesos zombies es el mismo: aquel cuyo PID es 9664.
En la versión de ps de GNU/Linux, también es posible recurrir a la opción l para mostrar la salida utilizando el formato largo de BSD. Esta salida incluye el PID del proceso padre para cada proceso (cuarta columna):
Se observa que el proceso padre de los zombies se encuentra en estado "sleeping". Por ende no se ha enterado de que sus hijos han muerto:
Entonces, o esperamos a que se entere por la sección necrológicas del periódico de mañana, o lo matamos para que no sufra enviándole la señal SIGKILL (kill -9):
Junto con el proceso padre desaparecen todos los zombies:
La respuesta corta era que se debe matar al proceso padre de cada zombie.
Debes estar registrado para ver los enlaces
. En sistemas operativos de la familia Unix, puede ocurrir que un proceso sea marcado como "zombie" o "difunto". Esta es una situación anormal. Haciendo una analogía terrible, tener procesos "zombie" en un sistema Unix, es como tener cadáveres pudriéndose en las calles. Es decir, muertos sin sepultar. Por ello han sido llamados zombies. Esto ocurre cuando un proceso finaliza su ejecución (termina), pero su padre (proceso que inició al proceso zombie) no está esperando por su finalización (no recibe el código de retorno). Un proceso "zombie" no existe como tal, ya no está en memoria y no utiliza CPU. Pero el núcleo del sistema operativo aún mantiene información acerca del mismo, el estado de salida o código de retorno, y está esperando que el proceso padre la reclame.
Entonces, un proceso "zombie" es una simple entrada en la tabla de procesos del núcleo del sistema operativo. Lo cual implica que no es posible matar un proceso "zombie", porque ya está muerto. Por más que se le envíen señales como kill -"hachazo en la cabeza", no va a desaparecer (digamos que no ocurre como en las series de zombies).
En este escenario hay dos alternativas: 1- el proceso padre finaliza y los procesos zombies son heredados por init, quien se encarga de recolectarlos y eliminarlos (reclamar su estado para que desaparezcan de la tabla de procesos del núcleo del sistema operativo); 2- Matar al proceso padre para forzar su desaparición.
La solución típica a este problema suele ser la segunda alternativa: matar al proceso padre para que desaparezcan los procesos zombies.
En general, los procesos zombies están asociados a malas prácticas de programación o falta de robustez de un programa. Cuando un proceso lanza procesos hijos, debe hacerse responsable por ellos, es decir, estar listo y esperar su eventual finalización, por más que no ellos no estén pensados para finalizar nunca.
De acuerdo al manual de ps en sistemas operativos GNU/Linux:
- Los procesos marcados como difuntos (<defunct>) son procesos muertos (llamados "zombies"). Estos procesos permanecen en el sistema porque su padre no los ha destruido adecuadamente. Estos procesos serán destruidos por init si el proceso padre finaliza.
De acuerdo al manual de ps en sistemas FreeBSD:
- Un proceso que ha terminado pero su padre no ha esperado por su finalización (en otras palabras, un zombie) es listado como "<defunct>".
Ejemplo de un caso real
Se trata de un servidor GNU/Linux corriendo un motor de bases de datos IBM Informix. Por causas anormales, una instancia de base de datos ha generado procesos zombies:
Código:
[root@informix666 ~]# ps aux | grep defunct
informix 9665 0.0 0.0 0 0 ? Z 11:46 0:00 [oninit.exe] <defunct>
informix 9666 0.0 0.0 0 0 ? Z 11:46 0:00 [oninit.exe] <defunct>
informix 9667 0.0 0.0 0 0 ? Z 11:46 0:00 [oninit.exe] <defunct>
root 9668 0.0 0.0 0 0 ? Z 11:46 0:00 [oninit.exe] <defunct>
root 9669 0.0 0.0 0 0 ? Z 11:46 0:00 [oninit.exe] <defunct>
root 9670 0.0 0.0 0 0 ? Z 11:46 0:00 [oninit.exe] <defunct>
root 9671 0.0 0.0 0 0 ? Z 11:46 0:00 [oninit.exe] <defunct>
root 9672 0.0 0.0 0 0 ? Z 11:46 0:00 [oninit.exe] <defunct>
root 9831 0.0 0.0 272 20 pts/1 R+ 12:14 0:00 grep defunct
Código:
ps -el | grep ‘Z
[/B]
Código:
[root@informix666 ~]# ps -eo pid,ppid | grep 9665
9665 9664
Código:
[root@informix666 ~]# ps -eo pid,ppid,command | grep defunct
9665 9664 [oninit.exe] <defunct>
9666 9664 [oninit.exe] <defunct>
9667 9664 [oninit.exe] <defunct>
9668 9664 [oninit.exe] <defunct>
9669 9664 [oninit.exe] <defunct>
9670 9664 [oninit.exe] <defunct>
9671 9664 [oninit.exe] <defunct>
9672 9664 [oninit.exe] <defunct>
En la versión de ps de GNU/Linux, también es posible recurrir a la opción l para mostrar la salida utilizando el formato largo de BSD. Esta salida incluye el PID del proceso padre para cada proceso (cuarta columna):
Código:
ps axl
Código:
[root@informix666 ~]# ps aux | grep 9664
root 9664 0.0 0.1 74464 1688 ? S 11:46 0:00 /opt/informix/bin/oninit.exe
root 9837 0.0 0.0 3748 736 pts/1 S+ 12:15 0:00 grep 9664
Código:
[root@informix666 ~]# kill -9 9664
Código:
[root@informix666 ~]# ps aux | grep defunct
root 9843 0.0 0.0 3748 728 pts/1 S+ 12:17 0:00 grep defunct