Prerrequisitos: fork() en C , Zombie Process
Zombie state: cuando se crea un proceso en UNIX mediante una llamada al sistema fork(), se replica el espacio de direcciones del proceso principal. Si el proceso padre llama al sistema wait(), entonces la ejecución del padre se suspende hasta que el hijo termine. Al finalizar el hijo, se genera una señal ‘SIGCHLD’ que el núcleo entrega al padre. Padre, al recibir ‘SIGCHLD’ lee el estado del hijo de la tabla de procesos. Aunque el hijo haya terminado, hay una entrada en la tabla de procesos correspondiente al hijo donde se almacena el estado. Cuando el padre recopila el estado, esta entrada se elimina. Por lo tanto, todos los rastros del proceso secundario se eliminan del sistema. Si el padre decide no esperar la terminación del niño y ejecuta su tarea subsiguiente, luego de la terminación del niño, el estado de salida no se lee. Por lo tanto, queda una entrada en la tabla de procesos incluso después de la terminación del hijo. Este estado del proceso hijo se conoce como estado Zombie.
C
// A C program to demonstrate working of // fork() and process table entries. #include<stdio.h> #include<unistd.h> #include<sys/wait.h> #include<sys/types.h> int main() { int i; int pid = fork(); if (pid == 0) { for (i=0; i<20; i++) printf("I am Child\n"); } else { printf("I am Parent\n"); while(1); } }
Producción :
Ahora revisa la tabla de procesos usando el siguiente comando en la terminal
$ps -eaf
Aquí la entrada [a.out] extinta muestra el proceso zombie.
¿Por qué necesitamos prevenir la creación del proceso Zombie?
Hay una tabla de procesos por sistema. El tamaño de la tabla de procesos es finito. Si se generan demasiados procesos zombies, la tabla de procesos estará llena. Es decir, el sistema no podrá generar ningún proceso nuevo, entonces el sistema se detendrá. Por lo tanto, debemos evitar la creación de procesos zombie.
Diferentes formas en que se puede prevenir la creación de Zombie
1. Uso de la llamada al sistema wait(): cuando el proceso principal llama a wait(), después de la creación de un hijo, indica que esperará a que el hijo se complete y obtendrá el estado de salida del hijo. El proceso principal se suspende (espera en una cola de espera) hasta que finaliza el proceso secundario. Debe entenderse que durante este período, el proceso padre no hace nada, solo espera.
C
// A C program to demonstrate working of // fork()/wait() and Zombie processes #include<stdio.h> #include<unistd.h> #include<sys/wait.h> #include<sys/types.h> int main() { int i; int pid = fork(); if (pid==0) { for (i=0; i<20; i++) printf("I am Child\n"); } else { wait(NULL); printf("I am Parent\n"); while(1); } }
2. Al ignorar la señal SIGCHLD: cuando se termina un hijo, se entrega una señal SIGCHLD correspondiente al padre, si llamamos a la ‘señal (SIGCHLD,SIG_IGN)’, entonces el sistema ignora la señal SIGCHLD y el hijo la entrada del proceso se elimina de la tabla de procesos. Por lo tanto, no se crea ningún zombi. Sin embargo, en este caso, el padre no puede conocer el estado de salida del niño.
C
// A C program to demonstrate ignoring // SIGCHLD signal to prevent Zombie processes #include<stdio.h> #include<unistd.h> #include<sys/wait.h> #include<sys/types.h> int main() { int i; int pid = fork(); if (pid == 0) for (i=0; i<20; i++) printf("I am Child\n"); else { signal(SIGCHLD,SIG_IGN); printf("I am Parent\n"); while(1); } }
3. Mediante el uso de un controlador de señales: el proceso principal instala un controlador de señales para la señal SIGCHLD. El manejador de señales llama al sistema wait() dentro de él. En este escenario, cuando el hijo termina, el SIGCHLD se entrega al padre. Al recibir SIGCHLD, se activa el controlador correspondiente, que a su vez llama a la llamada del sistema wait(). Por lo tanto, el padre recopila el estado de salida casi de inmediato y se borra la entrada del hijo en la tabla de procesos. Por lo tanto, no se crea ningún zombi.
C
// A C program to demonstrate handling of // SIGCHLD signal to prevent Zombie processes. #include<stdio.h> #include<unistd.h> #include<sys/wait.h> #include<sys/types.h> void func(int signum) { wait(NULL); } int main() { int i; int pid = fork(); if (pid == 0) for (i=0; i<20; i++) printf("I am Child\n"); else { signal(SIGCHLD, func); printf("I am Parent\n"); while(1); } }
Producción:
Aquí no hay ningún [a.out] inactivo, es decir, no se crea ningún proceso Zombie.
Este artículo es una contribución de Kishlay Verma . Si te gusta GeeksforGeeks y te gustaría contribuir, también puedes escribir un artículo usando write.geeksforgeeks.org o enviar tu artículo por correo a review-team@geeksforgeeks.org. Vea su artículo que aparece en la página principal de GeeksforGeeks y ayude a otros Geeks.
Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.
Publicación traducida automáticamente
Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA