Nuevo proceso padre cuando el proceso padre muere

22

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?

usuario100503
fuente

Respuestas:

5

Moviendo mi comentario a una respuesta ... No creo que haya excepciones.

Encontró esto "a veces el proceso primario se initelimina 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 initproceso 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 initproceso se convierte en su nuevo proceso padre ".

Simplemente yo
fuente
61

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_SUBREAPERopció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_ACQUIREy PROC_REAP_RELEASEopciones. 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.

Otras lecturas

JdeBP
fuente
De hecho, había notado que los procesos huérfanos se adjuntaban a una sesión init (en Ubuntu con Upstart), pero nunca me di cuenta de su importancia. +1
muru
Consulte unix.stackexchange.com/a/194208/5132 para obtener más información sobre el inicio de la sesión de arranque, específicamente.
JdeBP
8

De acuerdo con la exitpá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).

Cristian Ciupitu
fuente