Cualquiera que haya tratado con terminales Linux con cierta regularidad, se ha encontrado alguna vez en su vida con procesos "especiales" que no importa lo que hagan con ellos que no son capaz de "morir"; son procesos que están ahí "muertos" y que no consumen memoria RAM ni CPU, pero que el sistema todavía reconoce como existentes y que no importa lo que se haga con ellos que se resisten a desaparecer... Dichos procesos son llamados procesos zombie y si bien no tienen que causar problemas de rendimiento, su sola aparición hace que pensemos que dicho proceso está activo y pueden dar lugar a confusiones; es por eso que lo ideal es que ninguno de dichos zombies pululen por nuestro sistema operativo, por muy inofensivos que éstos sean.
Los procesos zombie siempre son procesos dependientes de un proceso "padre" que no ha sido capaz de finalizar correctamente sus procesos "hijo", haciendo que estos sigan existiendo en el sistema aún cuando no consuman recursos... Este fenómeno es fácilmente comprobable en cualquier consola de Linux; pero antes, para asegurarnos que efectivamente va a existir un proceso zombie, crearemos varios "zombies" nosotros mismos a modo de prueba de concepto. Para ello tendríamos que crear un pequeño programa escrito en c llamado, por ejemplo, zombiegen.c cuyo contenido sería:
- #include <stdlib.h>
- #include <stdio.h>
- int main() {
- pid_t pid;
- int i=0;
- while (1) {
- pid = fork();
- if (pid > 0) {
- // Proceso padre
- printf("Padre %d\n",i + 1);
- sleep(1);
- } else {
- // Proceso hijo
- printf("Zombie %d\n",i + 1);
- exit(0);
- }
- i++;
- }
- return 0;
- }
Después habría que compilar el programa mediante gcc tal que así:
gcc zombie.c -o zombie
Con esto haríamos que se creasen constantemente procesos zombie hasta que decidiésemos parar el programa. ¿Cómo podemos saber si el sistema tiene algún proceso zombie actualmente? Mediante el siguiente comando:
ps aux |grep defunct |grep -v grep
Al ser un bucle que crea procesos zombie constantemente podemos encontrarnos con algo como esto:
Ahora bien, ¿Cómo nos libramos de los zombies? Tan simple como matando al padre de todos éstos, con lo que lo primero que tendríamos que ver es... ¿Quien es el padre de todos estos? Si conociésemos el PID (process ID) del padre, podríamos "matar" este para así automáticamente acabar con sus hijos... Esto puede parecer complejo pero es tan sencillo como hacer:
ps -eo pid,ppid,command | grep defunct |grep -v grep
Con esto listaríamos el numero de proceso de cada zombie, seguido del número de proceso de aquel que ha "creado" el zombie, junto con el comando.
En mi caso en particular me aparecería esto:
Si nos fijamos bien, veremos que todos comparten el mismo PPID (Parent Process ID) ... Es decir que todos dependen de dicho proceso para seguir existiendo así que únicamente tendríamos que acabar con éste proceso mediante un simple kill. En este caso tendríamos que detener el proceso con PID 4636.
kill -9 4636
Tras lo cual únicamente tendríamos que volver a ejecutar nuestro anterior comando para ver que efectivamente hemos acabado con todos ellos.
Como veis, el encontrar y acabar con estos procesos es muy sencillo; solamente hay que buscar procesos "defunct" y acabar con el proceso que los está generando... Obviamente para acabar con la raíz del problema habría que ver qué error de programación hay en el proceso padre, pero esto puede servirnos como una solución temporal para limpiar los procesos zombie hasta encontrar el verdadero origen de esta situación.
Espero que os haya resultado útil.
Saludos.
No hay comentarios :
Publicar un comentario