En UNIX, cuando un proceso primario desaparece, pensé que todos los procesos secundarios restablecen init como sus padres. ¿No es esto correcto todo el tiempo? ¿Hay alguna excepción?
En UNIX, cuando un proceso primario desaparece, pensé que todos los procesos secundarios restablecen init como sus padres. ¿No es esto correcto todo el tiempo? ¿Hay alguna excepción?
Respuestas:
Moviendo mi comentario a una respuesta ... No creo que haya excepciones.
Encontró esto "a veces el proceso primario se init
elimina antes de que se elimine su elemento secundario. En este caso, el proceso" principal de todos los procesos " se convierte en el nuevo PPID (ID del proceso principal). En algún momento, estos procesos se denominan proceso huérfano". fuente
De manera similar se describe en el blog de IBM : "El padre muere o muere antes que el niño. En el escenario anterior, el proceso hijo se convierte en el proceso huérfano (ya que ha perdido a su padre). En Linux, el init
proceso viene al rescate del los procesos huérfanos y los adopta. Esto significa que después de que un niño ha perdido a su padre, el init
proceso se convierte en su nuevo proceso padre ".
Tres respuestas escritas en 2014, todas diciendo que en Unices y en Linux el proceso está reparentado para procesar el # 1 sin excepción. Tres respuestas equivocadas. ☺
Como dice el SUS , citado en una de las otras respuestas aquí, así que no lo citaré nuevamente, el proceso principal de los niños huérfanos se establece en un proceso definido por la implementación . Cristian Ciupitu tiene razón al consultar la documentación de Linux para ver qué define la implementación. Pero está siendo engañado por esa documentación, que es inconsistente y no está actualizada.
Dos años antes de que se escribieran estas tres respuestas, y rápidamente hasta hace tres años al momento de escribir esta respuesta, el kernel de Linux cambió. Los desarrolladores de systemd agregaron la capacidad de que los procesos se configuren como "subrepapers". A partir de Linux 3.4, los procesos pueden emitir la prctl()
llamada al sistema con la PR_SET_CHILD_SUBREAPER
opción y, como resultado, ellos, no el proceso n. ° 1, se convertirán en los padres de cualquiera de sus procesos descendientes huérfanos. La página de manual paraprctl()
está actualizada, pero otras páginas de manual no se han actualizado y no se han hecho coherentes.
En la versión 10.2, FreeBSD ganó la misma capacidad, extendiendo su procctl()
llamada al sistema existente con PROC_REAP_ACQUIRE
y PROC_REAP_RELEASE
opciones. Adoptó este mecanismo de DragonFly BSD; que lo ganó en la versión 4.2, originalmente nombrada reapctl()
pero renombrada durante el desarrollo de procctl()
.
Por lo tanto, hay excepciones y otras bastante destacadas: en Linux, FreeBSD / PC-BSD y DragonFly BSD, el proceso principal de los niños huérfanos se establece en el proceso ancestro más cercano del niño que está marcado como un subárea o proceso # 1 si no hay un proceso de antepasado subreaper. Varias utilidades de supervisión de daemon, incluido systemd (aquel cuyos desarrolladores pusieron esto en el kernel de Linux en primer lugar), upstart y nosh service-manager
, ya lo utilizan.
Si por ejemplo un supervisor demonio no se procese # 1, y se genera un servicio como una sesión de inicio de sesión interactiva, y en esa sesión se hace el truco (bastante equivocada) de intentar "daemonize" de doble fork()
ing , entonces el proceso de una voluntad terminar como un hijo del supervisor demonio, no del proceso # 1. Por supuesto, esperar poder generar demonios directamente desde las sesiones de inicio de sesión es un error fundamental. Pero esa es otra respuesta.
procctl()
. Páginas del manual de DragonFly BSD. § 2.De acuerdo con la exit
página de manual de The Single UNIX® Specification, Version 2:
El ID del proceso principal de todos los procesos secundarios y procesos zombies existentes del proceso de llamada se establece en el ID del proceso de un proceso del sistema dependiente de la implementación. Es decir, estos procesos son heredados por un proceso especial del sistema.
Para la mayoría de las variantes de Unix, ese proceso especial es init
(PID 1).
La wait(2)
página del manual de Linux confirma esto:
Si un proceso padre finaliza, init (8) adopta sus hijos "zombies" (si los hay), que automáticamente realiza una espera para eliminar a los zombies.
Las páginas de manual de FreeBSD wait(2)
, NetBSD wait(2)
, OpenBSD wait(2)
y Mac OS X también wait(2)
confirman esto:
Si un proceso primario finaliza sin esperar a que finalicen todos sus procesos secundarios, a los procesos secundarios restantes se les asigna la ID del proceso primario 1 (la ID del proceso de inicio).
La wait(3C)
página del manual de Oracle Solaris 11.1 también confirma esto:
Si un proceso primario finaliza sin esperar a que finalicen sus procesos secundarios, el ID del proceso primario de cada proceso secundario se establece en 1, y el proceso de inicialización hereda los procesos secundarios; ver
Intro(2)
.
No lo creo Siempre va al proceso de inicio.