stringtranslate.com

Proceso zombi

En los sistemas operativos Unix y similares , un proceso zombi o proceso inactivo es un proceso que ha completado su ejecución (a través de la llamada al sistema ) pero que aún tiene una entrada en la tabla de procesos : es un proceso en " estado terminado ". Esto ocurre con los procesos secundarios , donde la entrada aún es necesaria para permitir que el proceso primario lea el estado de salida de su proceso secundario : una vez que se lee el estado de salida a través de la llamada al sistema , la entrada del proceso zombi se elimina de la tabla de procesos y se dice que se "recoge". Un proceso secundario se convierte inicialmente en un proceso zombi, y solo entonces se lo elimina de la tabla de recursos. En condiciones normales de funcionamiento del sistema, los procesos zombi son inmediatamente atendidos por su proceso primario y luego son cosechados por el sistema. Los procesos que permanecen como zombis durante mucho tiempo suelen ser un error y pueden provocar una fuga de recursos . Generalmente, el único recurso del núcleo que ocupan es la entrada de la tabla de procesos, su ID de proceso. Sin embargo, los procesos zombi también pueden mantener búferes abiertos, consumiendo memoria. Los procesos zombi 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 la diferencia entre y . Si bien puede mostrar una gran cantidad de espacio libre en el disco, mostrará una partición llena. Si no se eliminan los zombies, esto puede llenar la partición raíz y bloquear el sistema.exit wait dudfdudf

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 ". A diferencia de los procesos normales, el killcomando no tiene efecto sobre un proceso zombi.

Los procesos zombie 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 hijo huérfano es adoptado por init. Cuando los procesos huérfanos mueren, no permanecen como procesos zombie, sino que son waitadoptados por init.

Descripción general

Cuando un proceso finaliza mediante exit, toda la memoria y los recursos asociados con él se liberan 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 hijo ejecutando la wait llamada del sistema , con lo que se elimina al zombi. La waitllamada puede ejecutarse en código secuencial, pero normalmente se ejecuta en un controlador para la señal SIGCHLD , que el padre recibe siempre que un hijo ha muerto.

Una vez eliminado el proceso zombi, se puede volver a utilizar su identificador de procesowait (PID) y la entrada en la tabla de procesos. Sin embargo, si un proceso padre no puede llamar a , el proceso zombi quedará en la tabla de procesos, lo que provocará una fuga de recursos . En algunas situaciones, esto puede ser deseable (el proceso padre desea seguir manteniendo este recurso); por ejemplo, si el proceso padre crea otro proceso hijo, se asegura de que no se le asignará el mismo PID. En los sistemas modernos similares a UNIX (que cumplen con la especificación SUSv3 en este sentido), se aplica el siguiente caso especial: si el proceso 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, se descartará toda la información de estado de salida del proceso hijo y no quedará ningún proceso zombi. [1]

Los procesos zombis pueden identificarse en la salida del ps comando Unix por la presencia de un " Z" en la columna "STAT". [2] Los procesos zombis que existen durante más de un corto período de tiempo normalmente indican un error en el programa padre, o simplemente una decisión poco común de no cosechar hijos (ver ejemplo). Si el programa padre ya no se está ejecutando, los procesos zombis normalmente indican un error en el sistema operativo. Al igual que con otras fugas de recursos, la presencia de unos pocos procesos zombis no es preocupante en sí misma, pero puede indicar un problema que se volvería serio bajo cargas más pesadas. Dado que no hay memoria asignada a los procesos zombis (el único uso de memoria del sistema es para la entrada de la tabla de procesos en sí), la principal preocupación con muchos procesos zombis no es quedarse sin memoria, sino quedarse sin entradas de la tabla de procesos, concretamente números de identificación de procesos. Sin embargo, los procesos zombis pueden mantener abiertos los búferes asociados con descriptores de archivos y, por lo tanto, hacer que el proceso zombi consuma memoria. Los procesos zombis también pueden mantener un descriptor de archivo para un archivo que se ha eliminado. Esto evita que el sistema de archivos recupere los i-nodos para el 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 zombie tiene el descriptor de archivo.

Para eliminar los zombis de un sistema, se puede enviar la señal SIGCHLD al proceso padre de forma manual, mediante el killcomando. Si el proceso padre sigue negándose a eliminar el zombi, y si no hay ningún problema con terminar el proceso padre, el siguiente paso puede ser eliminar el proceso padre. Cuando un proceso pierde a su padre, initse convierte en su nuevo padre. initejecuta periódicamente la waitllamada al sistema para eliminar cualquier zombi que tenga initcomo padre.

Ejemplo

La espera sincrónica de procesos secundarios específicos en un orden (específico) puede hacer que los zombis permanezcan presentes durante más tiempo que el "corto período de tiempo" mencionado anteriormente. No se trata necesariamente de un error del programa.

#include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h>    int principal ( void ) { pid_t pids [ 10 ]; int i ;      para ( i = 9 ; i >= 0 ; -- i ) { pids [ i ] = fork (); si ( pids [ i ] == 0 ) { printf ( "Hijo%d \n " , i ); dormir ( i + 1 ); _salir ( 0 ); } }                       para ( i = 9 ; i >= 0 ; -- i ) { printf ( "padre%d \n " , i ); waitpid ( pids [ i ], NULL , 0 ); }               devuelve 0 ; } 

Producción

padre9Niño3Niño 4Niño2Niño 5Niño1Niño6Niño0Niño7Niño8Niño9 // Hay una pausa aquí.padre8padre7padre6padre5padre4padre3padre2padre1padre0

Explicación

En el primer bucle, 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, se queda inactivo y sale. Todos los procesos secundarios se crean prácticamente al mismo tiempo (ya que el padre hace muy poco en el bucle), por lo que es algo aleatorio cuándo se programa cada uno de ellos por primera vez, de ahí el orden desordenado de sus mensajes.

Durante el bucle, se crea una matriz de identificadores de procesos secundarios. Hay una copia de la matriz pids[] en los 11 procesos, pero solo en el primario está completa: a la copia de cada secundario le faltarán los identificadores de proceso secundarios con números más bajos y tendrá cero como su propio identificador de proceso. (Esto no importa mucho, ya que solo el proceso primario usa realmente 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 salga cada hijo. Espera al hijo 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 orden aleatorio aquí, ya que está impulsado por un bucle en un solo proceso. El primer mensaje del padre en realidad apareció antes que cualquiera de los mensajes de los hijos: el padre pudo continuar en el segundo bucle antes de que cualquiera de los procesos hijos pudiera comenzar. Esto nuevamente es simplemente 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 salen y el momento en que el padre realiza una waitpid() en ellos. El padre ya estaba esperando a Child9 antes de que saliera, por lo que ese proceso no pasó prácticamente ningún tiempo como zombi. [3]

Véase también

Referencias

  1. ^ "Página de manual wait(2)". Manual del programador de Linux .
  2. ^ "Zombies(5) - UNIX System V (Conceptos)". El detector de colisiones en Fermilab .
  3. ^ "Linux: ¿Alguien puede explicar cómo funciona esto? fork(),sleep()".

Enlaces externos