stringtranslate.com

Proceso padre

En informática, un proceso padre es un proceso que ha creado uno o más procesos hijos .

Sistemas tipo Unix

En los sistemas operativos tipo Unix , cada proceso excepto el proceso 0 (el intercambiador) se crea cuando otro proceso ejecuta la llamada al sistema fork() . El proceso que invocó la bifurcación es el proceso padre y el proceso recién creado es el proceso hijo . Cada proceso (excepto el proceso 0) tiene un proceso padre, pero puede tener muchos procesos hijos.

El núcleo del sistema operativo identifica cada proceso por su identificador de proceso. El proceso 0 es un proceso especial que se crea cuando se inicia el sistema; después de bifurcar un proceso hijo (proceso 1), el proceso 0 se convierte en el proceso de intercambio (a veces también conocido como " tarea inactiva "). El proceso 1 , conocido como init , es el antepasado de todos los demás procesos del sistema. [1]

linux

En el kernel de Linux , en el que existe una diferencia muy pequeña entre procesos y subprocesos POSIX , hay dos tipos de procesos principales, a saber, padre real y padre. El padre es el proceso que recibe la señal SIGCHLD cuando el niño termina, mientras que el padre real es el hilo que realmente creó este proceso hijo en un entorno multiproceso. Para un proceso normal, estos dos valores son iguales, pero para un subproceso POSIX que actúa como proceso, estos dos valores pueden ser diferentes. [2]

Procesos zombies

El sistema operativo mantiene una tabla que asocia cada proceso, mediante su identificador de proceso (generalmente denominado " pid ") a los datos necesarios para su funcionamiento. Durante la vida de un proceso, dichos datos pueden incluir segmentos de memoria designados para el proceso, los argumentos con los que se ha invocado, variables de entorno , contadores sobre el uso de recursos, ID de usuario, ID de grupo y conjunto de grupos, y tal vez otros tipos de información.

Cuando un proceso finaliza su ejecución, ya sea llamando a exit (aunque sea implícitamente, ejecutando un comando de retorno de la función principal ) o recibiendo una señal que hace que finalice abruptamente, el sistema operativo libera la mayoría de los recursos e información relacionados con ese proceso, pero aún mantiene los datos sobre la utilización de recursos y el código de estado de terminación , porque un proceso padre podría estar interesado en saber si ese hijo se ejecutó exitosamente (mediante el uso de funciones estándar para decodificar el código de estado de terminación) y la cantidad de recursos del sistema que tiene. consumido durante su ejecución.

De forma predeterminada, el sistema supone que el proceso principal está realmente interesado en dicha información en el momento de la terminación del niño y, por lo tanto, envía al padre la señal SIGCHLD para alertar que hay algunos datos sobre un niño que deben recopilarse. Dicha recopilación se realiza llamando a una función de la familia de espera (ya sea la propia espera o uno de sus parientes, como waitpid , waitid o wait4 ). Tan pronto como se realiza esta recopilación, el sistema publica los últimos bits de información sobre el proceso hijo y elimina su pid de la tabla de procesos. Sin embargo, si el proceso principal se demora en recopilar los datos del niño (o no lo hace en absoluto), el sistema no tiene otra opción que mantener los datos pid y de terminación del niño en la tabla de procesos indefinidamente.

Un proceso terminado de este tipo cuyos datos no se han recopilado se denomina proceso zombie , o simplemente zombie , en el lenguaje UNIX. El nombre es una analogía humorística debido a que se considera un proceso terminado como "ya no vivo" o "muerto" (ya que realmente ha dejado de funcionar) y un proceso muerto persistente todavía "encarnado" en los procesos del "mundo de los vivos": el proceso mesa, que por lo tanto es en realidad "no-muerto" o "zombi".

Los procesos zombies pueden plantear problemas en sistemas con recursos limitados o que tienen tablas de procesos de tamaño limitado, ya que la creación de procesos nuevos y activos podría verse impedida por la falta de recursos que todavía utilizan los zombies de larga duración.

Por lo tanto, es una buena práctica de programación que cualquier programa que pueda generar procesos secundarios tenga un código que evite la formación de zombis duraderos a partir de sus hijos originales. El enfoque más obvio es tener un código que llame a esperar o a uno de sus parientes en algún lugar después de haber creado un nuevo proceso. Si se espera que el programa cree muchos procesos secundarios que pueden ejecutarse de forma asincrónica y terminar en un orden impredecible, generalmente es bueno crear un controlador para la señal SIGCHLD , llamando a una de las funciones de familia de espera en un bucle, hasta que no haya ningún proceso secundario sin recopilar. los datos permanecen. Es posible que el proceso padre ignore por completo la terminación de sus hijos y aun así no cree zombies, pero esto requiere la definición explícita de un controlador para SIGCHLD a través de una llamada a sigaction con la opción especial bandera SA_NOCLDWAIT . [3]

Procesos huérfanos

Los procesos huérfanos son una situación opuesta a los procesos zombies, refiriéndose al caso en el que un proceso padre termina antes que sus procesos hijos, que se dice que quedan "huérfanos". A diferencia de la notificación asincrónica de hijo a padre que ocurre cuando finaliza un proceso hijo (a través de la señal SIGCHLD ), los procesos hijos no reciben una notificación inmediata cuando finaliza su padre. En cambio, el sistema simplemente redefine el campo "PID principal" en los datos del proceso hijo para que sea el proceso que es el "antepasado" de todos los demás procesos en el sistema, cuyo PID generalmente tiene el valor de 1 (uno) y cuyo nombre es tradicionalmente "init" (excepto en el kernel de Linux 3.4 y superior [más información a continuación]). Por lo tanto, se dijo que init "adopta" todos los procesos huérfanos del sistema. [4] [5]

Una suposición algo común por parte de los programadores nuevos en UNIX era que los procesos secundarios de un proceso de terminación serán adoptados por el proceso padre inmediato de este proceso (de ahí el "abuelo" de esos procesos secundarios). Tal suposición era incorrecta, a menos, por supuesto, que ese "abuelo" fuera el propio init.

Después del kernel de Linux 3.4, esto ya no es cierto; de hecho, los procesos pueden emitir la llamada al sistema prctl() con la opción PR_SET_CHILD_SUBREAPER y, como resultado, ellos, no el proceso #1, se convertirán en el padre de cualquiera de sus procesos descendientes huérfanos. Esta es la forma de trabajar de los administradores de servicios modernos y de las utilidades de supervisión de demonios, incluidos systemd, upstart y nosh service manager.

Este es un resumen de la página del manual, que informa que:

Un subreaper cumple el rol de init(1) para sus procesos descendientes. Cuando un proceso queda huérfano (es decir, su padre inmediato termina), entonces ese proceso será reparentado al subsegador ancestro aún vivo más cercano. Posteriormente, las llamadas a getppid() en el proceso huérfano ahora devolverán el PID del proceso subreaper, y cuando el huérfano finalice, es el proceso subreaper el que recibirá una señal SIGCHLD y podrá esperar(2) en el proceso. para conocer su estado de terminación. [6]

Referencias

  1. ^ Tanenbaum, Andrés (2007). Sistemas operativos modernos (3ª ed.). Pearson-Prentice Hall. pag. 752.ISBN _ 978-0136006633.
  2. ^ Srinivasan, Sundar (1 de septiembre de 2010). "Las opciones y el futuro de un ingeniero: un adelanto del kernel de Linux - Capítulo 2: Creación de procesos". Sunnyeves.blogspot.com . Consultado el 30 de abril de 2014 .
  3. ^ "esperar página de manual - Llamadas al sistema". www.mankier.com .
  4. ^ "init es lo primero".
  5. ^ "Una descripción general de los procesos de Linux". IBM. 26 de marzo de 2012.
  6. ^ "Manual del programador de Linux".