Red de conocimiento informático - Problemas con los teléfonos móviles - ¿Cómo solucionar el problema del proceso zombie en ubuntu Linux?

¿Cómo solucionar el problema del proceso zombie en ubuntu Linux?

Linux permite que un proceso consulte al kernel para obtener el PID de su proceso padre o el estado de ejecución de cualquiera de sus procesos hijos. Por ejemplo, un proceso puede crear un proceso hijo para realizar una tarea específica y luego llamar a una función de biblioteca (como esperar()) para comprobar si el proceso hijo ha terminado. Si el proceso hijo ha terminado, su especificador de terminación le dice al proceso padre si la tarea se completó correctamente.

Para cumplir con estos principios de diseño, el kernel de Linux no permite que los datos contenidos en los campos del descriptor del proceso se descarten inmediatamente después de que finalice el proceso. Esto solo se permite después de que el proceso principal haya emitido una llamada al sistema de tipo wait() relacionada con el proceso terminado. Esta es la razón por la que se introdujo el estado inactivo: incluso si un proceso está técnicamente inactivo, sus descriptores deben permanecer hasta que se notifique al proceso principal.

Si un proceso ha terminado pero su proceso padre no ha llamado a wait() o waitpid() para limpiarlo, el estado del proceso se llama interbloqueo y el proceso en el estado de interbloqueo se llama Zombie. proceso. Cualquier proceso es un proceso zombie cuando finaliza. Normalmente, un proceso zombie es limpiado inmediatamente por su proceso padre.

Cómo se generan los procesos zombies En sistemas UNIX, un proceso se convertirá en un proceso zombie si finaliza sin que su proceso padre esté esperando (llamando a wait / waitpid). Encuéntrelo mediante el comando ps usando la bandera desaparecida. Un proceso zombie es un proceso que murió hace mucho tiempo pero que aún ocupa un espacio en la tabla de procesos.

Sin embargo, si el proceso padre de un proceso finaliza primero, no se convertirá en un proceso zombie. La razón es que cuando finaliza cada proceso, el sistema escaneará todos los procesos que se ejecutan en el sistema para ver si hay procesos secundarios del proceso que acaba de finalizar. Si es así, el proceso Init tomará el control y se convertirá en su proceso principal. , asegurando así que cada proceso Cada proceso tenga un proceso padre. El proceso Init espera automáticamente la llegada de sus procesos secundarios, por lo que el proceso asumido por Init no se convertirá en un proceso zombie.

Para observar el proceso zombie, escribimos nuestro propio programa de excepción, en el que el proceso padre bifurca el proceso hijo, el proceso hijo termina y el proceso padre no termina ni llama a esperar para limpiar el proceso hijo:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

2122

23

24

25

26

27

#include <unistd.h>

#include

#include

#include

#include

fork() ;

error("fork()", getpid());

error("failed.0; i--)

{ dormir(1 );

} } else?if(pid == 0) {

printf("Este es el proceso hijo. Mi PID es: %d. Mi PPID es: %d . \n", getpid(), getppid(), getppid());

printf("Este es el proceso padre. getpid(), getppid()); p >

}

Guarde el código anterior en el archivo zomprocdemo.c y luego ejecute el siguiente comando para compilarlo:

1

$ gcc zomprocdemo.c -o zomprocdemo

Luego ejecute el programa compilado zomprocdemo:

1

$ ./zomprocdemo

Haga clic para ingresar una descripción

En este punto, el El proceso hijo ha salido, pero el proceso padre no ha salido, ni el proceso hijo ha sido procesado llamando a wait(). Usamos el comando ps para ver el estado del proceso:

Haga clic para ingresar la descripción de la imagen

La "Z" mayúscula en el cuadro rojo de arriba indica que el proceso con PID 112712 está en punto muerto en este momento.

¡Continuemos! El proceso principal sale al final del sueño. Una vez que sale el proceso principal, el proceso secundario queda huérfano y es adoptado por el proceso de alojamiento. En diferentes sistemas, este suele ser el proceso de inicio, o el advenedizo en Ubuntu, o más recientemente Systemd, pero todos hacen lo mismo, que es wiat() los procesos huérfanos y eventualmente liberarlos en los recursos ocupados de la tabla de procesos del sistema. De esta forma, estos procesos “huérfanos” serán eliminados por completo del sistema.

El peligro de los procesos zombies

Cuando un proceso sale, el kernel liberará todos los recursos del proceso, incluidos archivos abiertos, memoria ocupada, etc. Sin embargo, el kernel aún conservará cierta información sobre el proceso (incluido el número de proceso PID, el estado de terminación del proceso, el tiempo de CPU ocupado por el proceso, etc.). No se publicará hasta que wait/waitpid controle el proceso principal.

Si el proceso no llama a wait/waitpid, la información retenida no se liberará y el número de proceso seguirá ocupado, pero la cantidad de números de proceso que el sistema puede usar es limitada, por lo que si un Se genera una gran cantidad de procesos inactivos. El sistema no podrá generar un nuevo proceso porque no hay un número de proceso disponible.

Cómo lidiar con procesos zombies

Los procesos zombies se generan porque el proceso padre no espera() al proceso hijo. Por lo tanto, si escribimos nuestro propio programa, debemos pasar wait() en el proceso padre para evitar crear procesos zombies.

Cuando aparece un proceso zombie en el sistema, no podemos utilizar el comando kill para eliminarlo. Sin embargo, podemos eliminar su proceso principal para que se convierta en un proceso huérfano y sea adoptado y limpiado por el proceso que administra los procesos huérfanos en el sistema.

En la siguiente demostración, el proceso padre utiliza wait() para esperar a que finalice el proceso hijo:

1

2

3

p>

4

5

6

7

8

9

10

11