Objetivo: Analizar cómo se crean procesos zombis o procesos difuntos y cómo eliminarlos de la tabla de procesos.
Un proceso zombi o un proceso extinto es un proceso que ha completado la ejecución pero que aún tiene una entrada en la tabla de procesos. Esto ocurre para procesos hijos que han sido bifurcados por un proceso padre usando la llamada al sistema fork()
pero no cosechados por el proceso padre usando la llamada al sistema wait()
.
El proceso padre tiene que hacer una llamada al sistema wait()
(o waitpid()
) para obtener el estado de salida del proceso hijo una vez que el proceso hijo haya terminado. Si el proceso padre no realiza la llamada wait()
, el proceso hijo se convertirá en un proceso zombi.
Se envía una señal SIGCHLD
al proceso padre cada vez que finaliza un proceso hijo. El proceso padre necesita tener una función de manejador de señales SIGCHLD
definida con una llamada a wait()
– esto eliminará el proceso hijo de la tabla de procesos.
Para eliminar procesos zombis de un sistema, la señal SIGCHLD
se puede enviar al padre manualmente, utilizando el comando kill
. Si el proceso padre todavía se niega a cosechar el proceso zombi, y si el proceso padre puede ser asesinado, el siguiente paso es matar al proceso padre. Cuando un proceso hijo pierde su proceso padre, init
(PID 1) se convierte en su nuevo padre. init
ejecuta periódicamente la llamada al sistema wait()
para obtener cualquier proceso zombi con init
como padre.
Escribí un simple programa en C para crear un proceso zombi.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
#include <stdio.h>
#incluye < stdlib.h>
#incluye < sys / types.h>
#incluir < sys / wait.h>
#incluir < unistd.h>
#incluir < errno.h>
int main ()
{
pid_t child_pid;
int child_status;
child_pid = fork ();
si (child_pid > 0) {
// proceso primario va a dormir durante 30 segundos y a la salida, sin una llamada a wait()
fprintf(stderr,»proceso primario – %d\n», getpid());
el sueño(30);
salida(0);
}
else if (child_pid == 0) {
// proceso hijo va a salir inmediatamente
fprintf(stderr,»hijo de proceso %d\n», getpid());
salida(0);
}
else if (child_pid == -1) {
// fork() error
perror(«fork() error de llamada»);
exit (-1);
}
else {
// esto no debería ocurrir
fprintf(stderr, «se desconoce el valor de retorno de %d de fork() call», child_pid);
exit (-2);
}
volver 0;
}
|
Guarde el código anterior como zombie.c
y compilar usando gcc
.
$ gcc zombie.c -o zombie
A continuación, ejecute el programa.
$ ./zombie parent process - 26570child process - 26571
Desde otro terminal, haga un ps
para mostrar los procesos en ejecución. Verás un proceso zombi.
$ ps -ef | grep zombieibrahim 26570 22886 0 15:59 pts/2 00:00:00 ./zombieibrahim 26571 26570 0 15:59 pts/2 00:00:00 <defunct>
Una vez que el proceso padre haya terminado (después de 30 segundos), el proceso zombi será eliminado de la tabla de procesos por el proceso init
.
Mohamed Ibrahim
ibrahim = { interested_in (unix, linux, android, open_source, ingeniería inversa); codificación (c, shell, php, python, java, javascript, nodejs, react); plays_on (xbox, ps4); linux_desktop_user (true); }