Nuovo processo padre quando il processo padre muore


22

In UNIX, quando un processo genitore scompare, ho pensato che tutti i processi figlio resettassero init come loro genitore. Non è sempre corretto? Ci sono delle eccezioni?

Risposte:


5

Sposta il mio commento in una risposta .... Non credo ci siano eccezioni.

Trovato questo "a volte il processo padre viene interrotto prima che il figlio venga ucciso. In questo caso, il processo" padre di tutti i processi " initdiventa il nuovo PPID (ID processo padre). A volte questi processi vengono chiamati processo orfano". fonte

Allo stesso modo è descritto nel blog di IBM : "Il genitore muore o viene ucciso prima del figlio. Nello scenario sopra, il processo figlio diventa il processo orfano (poiché ha perso il suo genitore). In Linux, il initprocesso viene in soccorso del i processi orfani li adotta e li adotta. Ciò significa che dopo che un bambino ha perso il genitore, il initprocesso diventa il suo nuovo processo genitore. "


61

Tre risposte scritte nel 2014, tutte affermano che in Unices e in Linux il processo è stato rinnovato per elaborare il numero 1 senza eccezioni. Tre risposte sbagliate. ☺

Come dice il SUS , citato in una delle altre risposte qui, quindi non lo citerò più, il processo genitore dei bambini orfani è impostato su un processo definito dall'implementazione . Cristian Ciupitu ha ragione a consultare la documentazione di Linux per vedere cosa definisce l'implementazione. Ma viene ingannato da quella documentazione, che è incoerente e non aggiornata.

Due anni prima che queste tre risposte fossero scritte, e arrivando rapidamente fino a tre anni fa al momento della prima scrittura di questa risposta, il kernel di Linux è cambiato. Gli sviluppatori di systemd hanno aggiunto la possibilità per i processi di configurarsi come "subreapers". A partire da Linux 3.4 i processi possono emettere la prctl()chiamata di sistema con l' PR_SET_CHILD_SUBREAPERopzione e, di conseguenza, non, il processo n. 1, diventeranno i genitori di uno qualsiasi dei loro processi discendenti orfani. La pagina man diprctl() è aggiornata, ma altre pagine man non sono state aggiornate e rese coerenti.

Nella versione 10.2, FreeBSD ha acquisito la stessa abilità, estendendo la sua procctl()chiamata di sistema esistente con PROC_REAP_ACQUIREe le PROC_REAP_RELEASEopzioni. Ha adottato questo meccanismo da DragonFly BSD; che lo ottenne nella versione 4.2, originariamente chiamata reapctl()ma ribattezzata durante lo sviluppo in procctl().

Quindi ci sono eccezioni, e abbastanza importanti: su Linux, FreeBSD / PC-BSD e DragonFly BSD, il processo genitore dei bambini orfani è impostato sul processo antenato più vicino del bambino che è contrassegnato come subreaper, o processo # 1 se non esiste un processo di subreaper degli antenati. Diverse utility di supervisione dei demoni - incluso systemd (quello i cui sviluppatori lo hanno inserito nel kernel Linux in primo luogo), upstart e nosh service-manager- lo usano già.

Se tale un supervisore daemon non è un processo # 1, e genera un servizio come una sessione di login interattiva, e in quella sessione si fa il (abbastanza wrongheaded) trick di tentare di "demonizzare" di doppio fork()ING , quindi proprio processo sarà finisce come figlio del supervisore del demone, non del processo n. 1. Aspettarsi di essere in grado di generare direttamente daemon all'interno delle sessioni di accesso è ovviamente un errore fondamentale. Ma questa è un'altra risposta.

Ulteriori letture


In realtà avevo notato che i processi orfani si erano collegati a un init di sessione (su Ubuntu con Upstart), ma non ne avevo mai capito il significato. +1
muru,

Vedi unix.stackexchange.com/a/194208/5132 per ulteriori informazioni sull'inizializzazione della sessione di avvio, in particolare.
JdeBP,

8

Secondo il exit pagina man di The Single UNIX® Specification, Versione 2:

L'ID del processo padre di tutti i processi figlio esistenti e i processi zombie del processo chiamante è impostato sull'ID processo di un processo di sistema dipendente dall'implementazione. Cioè, questi processi sono ereditati da un processo di sistema speciale.

Per la maggior parte delle varianti Unix, quel processo speciale è init(PID 1).

La wait(2)pagina man di Linux lo conferma:

Se termina un processo genitore, i suoi figli "zombi" (se presenti) vengono adottati da init (8), che esegue automaticamente un'attesa per rimuovere gli zombi.

Anche le pagine man di FreeBSD wait(2), NetBSD wait(2), OpenBSD wait(2)e Mac OS X lo wait(2)confermano:

Se un processo genitore termina senza attendere il termine di tutti i suoi processi figlio, ai processi figlio rimanenti viene assegnato l'ID processo 1 padre (l'ID processo init).

Oracle Solaris 11.1 wait(3C) pagina man conferma anche:

Se un processo parent termina senza attendere che i processi child vengano terminati, l'ID del processo parent di ciascun processo child viene impostato su 1, con il processo di inizializzazione che eredita i processi child; vedi Intro(2).


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.