stringtranslate.com

proceso zombi

En Unix y sistemas operativos de computadora similares a Unix , un proceso zombie o proceso difunto es un proceso que ha completado su ejecución (a través de la 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 la entrada aún es necesaria 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 , la entrada del zombi se elimina de la tabla de procesos y se dice que ser "cosechado". Inicialmente, un proceso hijo se convierte en un zombi y solo luego se elimina de la tabla de recursos. Bajo el funcionamiento normal del sistema, los zombis son inmediatamente atendidos por sus padres y luego cosechados por el sistema. Los procesos que permanecen zombis durante mucho tiempo suelen ser un error y pueden provocar una fuga de recursos . Generalmente, el único recurso del kernel que ocupan es la entrada de la tabla de procesos, su ID de proceso. Sin embargo, los zombis también pueden mantener abiertos los buffers, consumiendo memoria. Los zombis pueden contener identificadores de descriptores de archivos, lo que evita que el espacio para esos archivos esté disponible para el sistema de archivos. Este efecto se puede ver por una diferencia entre y . Si bien puede mostrar una gran cantidad de espacio libre en el disco, mostrará una partición completa. Si los zombies no se limpian, esto puede llenar la partición raíz y bloquear el sistema.exit wait dudfdudf

El término proceso zombie deriva de la definición común de zombie : una persona no muerta . En la metáfora del término, el proceso hijo ha "muerto" pero aún no ha sido " cosechado ". A diferencia de los procesos normales, el killcomando no tiene ningún efecto en un proceso zombie.

Los procesos zombies no deben confundirse con los procesos huérfanos , un proceso que aún se está ejecutando, pero cuyo padre ha muerto. Cuando el padre muere, el proceso del niño huérfano es adoptado por init. Cuando los procesos huérfanos mueren, no permanecen como procesos zombies; en cambio, son waitguiados por init.

Descripción general

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 wait llamada al sistema , tras lo cual se elimina el zombi. La waitllamada 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 un niño muere.

Una vez eliminado el zombi, se pueden reutilizar su identificador de proceso (PID) y su entrada en la tabla de procesos. Sin embargo, si uno de los padres no llama wait, el zombi quedará en la tabla de procesos, provocando 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 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 configurando su controlador en SIG_IGN(en lugar de simplemente ignorar la señal de forma predeterminada) o tiene el SA_NOCLDWAITindicador configurado, Toda la información del estado de salida del niño se descartará y no quedará ningún proceso zombie. [1]

Los zombis se pueden identificar en la salida del ps comando Unix por la presencia de " Z" en la columna "STAT". [2] Los zombis que existen durante 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 niños (ver ejemplo). Si el programa principal ya no se ejecuta, 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 podría agravarse 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 con los números de identificación de los procesos. Sin embargo, los zombis pueden mantener búferes abiertos asociados con descriptores de archivos y, por lo tanto, hacer que el zombi consuma memoria. Los zombis también pueden contener un descriptor de archivo de un archivo que ha sido eliminado. Esto evita que el sistema de archivos recupere los i-nodos del archivo eliminado. Por lo tanto, el comando para mostrar el uso del disco no contará los archivos eliminados cuyo espacio no se puede reutilizar debido a que el zombi tiene el descriptor de archivo.

Para eliminar zombies de un sistema, la señal SIGCHLD se puede enviar al padre manualmente, usando el killcomando. Si el proceso principal aún se niega a cosechar al zombie, 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, initse convierte en su nuevo padre. initejecuta periódicamente la waitllamada al sistema para cosechar cualquier zombie que tenga initcomo padre.

Ejemplo

Esperar sincrónicamente los procesos secundarios específicos en un orden (específico) puede dejar a los zombis presentes por más tiempo que el "corto período de tiempo" mencionado anteriormente. No es necesariamente un error del programa.

#incluye <sys/wait.h> #incluye <stdio.h> #incluye <stdlib.h> #incluye <unistd.h>    int principal ( vacío ) { pid_t pids [ 10 ]; int yo ;      for ( i = 9 ; i >= 0 ; - i ) { pids [ i ] = fork (); if ( pids [ i ] == 0 ) { printf ( "Niño%d \n " , i ); dormir ( yo + 1 ); _salir ( 0 ); } }                       for ( i = 9 ; i >= 0 ; - i ) { printf ( "padre%d \n " , i ); waitpid ( pids [ i ], NULL , 0 ); }               devolver 0 ; } 

Producción

padre9niño3niño4niño2niño5Niño1niño6Niño0niño7niño8Child9 // hay una pausa aquípadre8padre7padre6padre5padre4padre3padre2padre1padre0

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 hace muy poco en el ciclo), por lo que es algo aleatorio cuando cada uno de ellos se programa por primera vez, de ahí el orden codificado de sus mensajes.

Durante el ciclo, se crea una serie 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 bucle 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ó primero 10 segundos; Todos los demás salieron hace mucho tiempo, por lo que todos los mensajes (excepto el primero) aparecen en rápida sucesión. Aquí no hay posibilidad de realizar un pedido aleatorio, ya que es impulsado por un bucle en un solo proceso. 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 iniciarse. Nuevamente, esto es solo el comportamiento aleatorio del programador de procesos: el mensaje "parent9" podría haber aparecido en cualquier parte de la secuencia anterior a "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() sobre ellos. El padre ya estaba esperando a Child9 antes de que saliera, por lo que un proceso prácticamente no pasó tiempo como zombi. [3]

Ver también

Referencias

  1. ^ "esperar (2) página de manual". Manual del programador de Linux .
  2. ^ "Zombis (5) - Sistema UNIX V (Conceptos)". El detector de colisionadores del Fermilab .
  3. ^ "Linux: ¿Alguien puede explicar cómo funciona esto? fork(),sleep()".

enlaces externos