En Unix y Unix informáticos sistemas operativos , un proceso zombie o proceso desaparecida es un proceso que ha finalizado su ejecución (a través de la exit
llamada al sistema ), pero aún tiene una entrada en la tabla de procesos : es un proceso en el " estado terminado ". Esto ocurre para los procesos secundarios , donde la entrada aún es necesaria para permitir que el proceso padre lea el estado de salida de su hijo : una vez que el estado de salida se lee a través de la llamada al wait
sistema, la entrada del zombi se elimina de la tabla de proceso y se dice que se "cosecha". Un proceso hijo siempre se convierte primero en un zombi antes de ser eliminado de la tabla de recursos. En la mayoría de los casos, en condiciones normales de funcionamiento del sistema, los zombis son atendidos inmediatamente por sus padres y luego el sistema los cosecha; los procesos que permanecen zombis durante mucho tiempo son generalmente un error y provocan 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 del niño ha "muerto" pero aún no ha sido " cosechado ". Además, a diferencia de los procesos normales, el kill
comando no tiene ningún efecto en un proceso zombie.
Los procesos zombis no deben confundirse con los procesos huérfanos : un proceso huérfano es un proceso que aún se está ejecutando, pero cuyo padre ha muerto. Cuando el padre muere, el proceso del hijo huérfano es adoptado por init
(ID de proceso 1). Cuando los procesos huérfanos mueren, no permanecen como procesos zombis; en cambio, son wait
editados por init
. El resultado es que un proceso que es a la vez zombi y huérfano se cosechará automáticamente.
Descripción general
Cuando un proceso termina 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 wait
llamada al sistema , tras lo cual se elimina al zombi. La wait
llamada puede ejecutarse en código secuencial, pero comúnmente se ejecuta en un controlador para la señal SIGCHLD , que el padre recibe cada vez que muere un hijo.
Una vez que se elimina el zombi, su identificador de proceso (PID) y la entrada en la tabla de proceso se pueden reutilizar. Sin embargo, si un padre no llama wait
, el zombi quedará en la tabla de procesos, lo que provocará una pérdida 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 asignará el mismo PID. En los sistemas modernos tipo UNIX (que cumplen con la especificación SUSv3 a este respecto), se aplica el siguiente caso especial: si el padre ignora explícitamente SIGCHLD estableciendo su controlador en SIG_IGN
(en lugar de simplemente ignorar la señal por defecto) o tiene la SA_NOCLDWAIT
bandera activada, Se descartará toda la información del estado de salida del niño y no quedará ningún proceso zombi. [1]
Los zombis se pueden identificar en la salida del ps
comando Unix por la presencia de un " Z
" en la columna "STAT". [2] 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 está ejecutando, los procesos zombies 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 zombies (el único uso de memoria del sistema es para la entrada de la tabla de procesos en sí), la principal preocupación de muchos zombies no es quedarse sin memoria, sino quedarse sin entradas de la tabla de procesos, concretamente números de ID de proceso.
Para eliminar zombis de un sistema, la señal SIGCHLD se puede enviar al padre manualmente, usando el kill
comando. Si el proceso principal aún se niega a cosechar al zombi, y si estaría bien terminar el proceso principal, el siguiente paso puede ser eliminar el proceso principal. Cuando un proceso pierde a su padre, se init
convierte en su nuevo padre. init
ejecuta periódicamente la wait
llamada al sistema para cosechar zombies con el init
padre.
Ejemplo
Esperar sincrónicamente los procesos secundarios específicos en un orden (específico) puede dejar a los zombis presentes más tiempo que el "breve período de tiempo" mencionado anteriormente. No es necesariamente un error del programa.
#include #include #include int main ( void ) { pid_t pids [ 10 ]; int i ; para ( i = 9 ; i > = 0 ; - i ) { pids [ i ] = fork (); if ( pids [ i ] == 0 ) { printf ( "Niño% d \ n " , i ); dormir ( i + 1 ); _exit ( 0 ); } } para ( i = 9 ; i > = 0 ; - i ) { printf ( "padre% d \ n " , i ); waitpid ( pids [ i ], NULL , 0 ); } return 0 ; }
Producción
padre9Niño3Niño4Niño2Niño5Niño1Niño6Niño0Niño7Niño8Child9 // aquí hay una pausaparent8padre7padre6parent5parent4padre3padre2padre1padre0
Explicación
En el primer ciclo, el proceso original (padre) 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 está haciendo muy poco en el ciclo), 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 ciclo, 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á completo; a la copia de cada hijo le faltarán los PID del hijo de menor número y tendrá cero para su propio PID. (No es que esto realmente importe, ya que solo el proceso principal realmente 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. No hay posibilidad de ordenar aleatoriamente aquí, ya que es impulsado por un bucle en un solo proceso. Tenga en cuenta que el primer mensaje principal apareció antes que cualquiera de los mensajes secundarios; el padre pudo continuar en el segundo ciclo antes de que cualquiera de los procesos secundarios pudiera comenzar. De nuevo, esto es solo el comportamiento aleatorio del programador de procesos: el mensaje "parent9" 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 salir, por lo que un proceso prácticamente no pasó tiempo como un zombi. [3]
Ver también
Referencias
- ^ "Espere (2) Página de manual" . Manual del programador de Linux .
- ^ "Zombies (5) - UNIX System V (Conceptos)" . El detector de colisionadores en Fermilab .
- ^ https://stackoverflow.com/questions/42627411/can-someone-please-explain-how-this-worksfork-sleep
- "Páginas de manual de UNIX: ps ()" . UNIXhelp para usuarios . Archivado desde el original el 8 de marzo de 2013.