Proceso zombi
En sistemas operativos informáticos Unix y similares a Unix, un proceso zombi o proceso difunto es un proceso que ha completado la ejecución (a través de la tecla salir
llamada al sistema) pero todavía tiene una entrada en la tabla de procesos: es un proceso en el "estado Terminado". Esto ocurre para los procesos secundarios, donde aún se necesita la entrada para permitir que el proceso principal lea el estado de salida de su hijo: una vez que se lee el estado de salida a través de la llamada al sistema wait
, el zombie& La entrada #39 se elimina de la tabla de procesos y se dice que se 'cosechó'. Un proceso secundario siempre se convierte primero en un zombi antes de ser eliminado de la tabla de recursos. En la mayoría de los casos, bajo el funcionamiento normal del sistema, los zombis son atendidos inmediatamente por su padre y luego son recogidos por el sistema: los procesos que permanecen zombis durante mucho tiempo generalmente son un error y causan una fuga de recursos, pero el único recurso que ocupan es el proceso. entrada de tabla – ID de proceso.
El término proceso zombi se deriva de la definición común de zombi: una persona no muerta. En la metáfora del término, el proceso hijo ha 'muerto'. pero aún no ha sido "cosechado". Además, a diferencia de los procesos normales, el comando kill
no tiene efecto en un proceso zombie.
Los procesos zombis no deben confundirse con los procesos huérfanos: un proceso huérfano es un proceso que todavía se está ejecutando, pero cuyo padre ha muerto. Cuando el padre muere, init
(ID de proceso 1) adopta el proceso hijo huérfano. Cuando los procesos huérfanos mueren, no quedan como procesos zombis; en su lugar, son wait
activados por init
. El resultado es que un proceso que es a la vez zombi y huérfano se cosechará automáticamente.
Resumen
Cuando un proceso finaliza a través de exit
, toda la memoria y los recursos asociados con él se desasignan para que puedan ser utilizados por otros procesos. Sin embargo, la entrada del proceso en la tabla de procesos permanece. El padre puede leer el estado de salida del niño ejecutando la llamada al sistema wait
, después de lo cual se elimina al zombi. La llamada wait
puede ejecutarse en código secuencial, pero normalmente se ejecuta en un controlador para la señal SIGCHLD, que el padre recibe cada vez que muere un hijo.
Después de eliminar el zombi, su identificador de proceso (PID) y la entrada en la tabla de procesos se pueden reutilizar. Sin embargo, si un padre no llama a wait
, el zombi se quedará en la tabla de procesos, lo que provocará una fuga de recursos. En algunas situaciones, esto puede ser deseable: el proceso padre desea continuar manteniendo este recurso; por ejemplo, si el padre crea otro proceso hijo, se asegura de que no se le asigne el mismo PID. En los sistemas modernos similares a UNIX (que cumplen con la especificación SUSv3 a este respecto), se aplica el siguiente caso especial: si el padre explícitamente ignora SIGCHLD configurando su controlador en SIG_IGN
(en lugar de simplemente ignorar la señal de forma predeterminada) o tiene el indicador SA_NOCLDWAIT
establecido, toda la información de estado de salida secundaria se descartará y no quedará ningún proceso zombie.
Los zombis se pueden identificar en la salida del comando ps
de Unix por la presencia de una "Z
" en el "ESTADO" columna. Los zombis que existen por más de un corto período de tiempo generalmente indican un error en el programa principal, o simplemente una decisión poco común de no cosechar hijos (ver ejemplo). Si el programa principal ya no se ejecuta, los procesos zombis suelen indicar un error en el sistema operativo. Al igual que con otras fugas de recursos, la presencia de algunos zombis no es preocupante en sí misma, pero puede indicar un problema que se agravaría con cargas más pesadas. Dado que no hay memoria asignada a los procesos zombis, el único uso de la memoria del sistema es para la entrada de la tabla de procesos en sí misma, la preocupación principal con muchos zombis no es quedarse sin memoria, sino quedarse sin entradas de la tabla de procesos, concretamente procesar números de ID.
Para eliminar zombis de un sistema, la señal SIGCHLD se puede enviar al padre manualmente, usando el comando kill
. Si el proceso principal aún se niega a cosechar el zombi, y si estaría bien terminar el proceso principal, el siguiente paso puede ser eliminar el proceso principal. Cuando un proceso pierde su padre, init
se convierte en su nuevo padre. init
ejecuta periódicamente la llamada al sistema wait
para cosechar cualquier zombi con init
como principal.
Ejemplo
Sincrónicamente esperar los procesos secundarios específicos en un orden (específico) puede dejar a los zombis presentes por más tiempo que el "período corto de tiempo" mencionado anteriormente. No es necesariamente un error del programa.
#include > > >#include Identificado.h#include ■stdlib.h#include No identificado.hint principal()vacío){} pid_t pids[10]; int i; para ()i = 9; i >= 0; --i) {} pids[i] = tenedor(); si ()pids[i] == 0) {} printf()"Child%dn", i); dormir()i+1); -Exacto.()0); } } para ()i = 9; i >= 0; --i) {} printf()"Padre"n", i); Waitpid()pids[i] NULL, 0); } retorno 0;}
Salida
padres9 Niño3 Niño4 Niño2 Niño5 Niño1 Niño6 Niño0 Niño7 Niño8 Child9 // hay una pausa aquí parent8 parent7 parent6 padres parent4 padre 3 parent2 progenitores parent0
Explicación
En el primer bucle, el proceso original (principal) bifurca 10 copias de sí mismo. Cada uno de estos procesos secundarios (detectados por el hecho de que fork() devolvió cero) imprime un mensaje, duerme y sale. Todos los hijos se crean esencialmente al mismo tiempo (ya que el padre hace muy poco en el bucle), por lo que es algo aleatorio cuando cada uno de ellos se programa por primera vez, por lo tanto, el orden codificado de sus mensajes.
Durante el bucle, se crea una matriz de ID de procesos secundarios. Hay una copia de la matriz pids[] en los 11 procesos, pero solo en el padre está completa: a la copia en cada hijo le faltarán los PID secundarios con números más bajos y tendrá cero para su propio PID. (No es que esto realmente importe, ya que solo el proceso principal usa esta matriz).
El segundo ciclo se ejecuta solo en el proceso padre (porque todos los hijos han salido antes de este punto) y espera a que cada hijo salga. Espera al niño que durmió 10 segundos primero; todos los demás han salido hace mucho tiempo, por lo que todos los mensajes (excepto el primero) aparecen en rápida sucesión. Aquí no hay posibilidad de ordenar aleatoriamente, ya que es impulsado por un ciclo en un solo proceso. Tenga en cuenta que el primer mensaje principal apareció antes que cualquiera de los mensajes secundarios: el principal pudo continuar en el segundo ciclo antes de que cualquiera de los procesos secundarios pudiera comenzar. Nuevamente, esto es solo el comportamiento aleatorio del programador de procesos: el "parent9" el mensaje podría haber aparecido en cualquier lugar de la secuencia antes de 'parent8'.
Child0 a Child8 pasan uno o más segundos en este estado, entre el momento en que salieron y el momento en que el padre hizo un waitpid() en ellos. El padre ya estaba esperando a Child9 antes de que saliera, por lo que un proceso esencialmente no pasó tiempo como un zombi.
Contenido relacionado
Modelo de color RGB
Lenguaje sensible al contexto
Filtro digital