Processo genitore - Parent process

In informatica, un processo genitore è un processo che ha creato uno o più processi figli .

Sistemi simili a Unix

Nei sistemi operativi Unix-like , ogni processo eccetto il processo 0 (lo swapper) viene creato quando un altro processo esegue la chiamata di sistema fork () . Il processo che ha invocato il fork è il processo padre e il processo appena creato è il processo figlio . Ogni processo (eccetto il processo 0) ha un processo genitore, ma può avere molti processi figli.

Il kernel del sistema operativo identifica ogni processo tramite il suo identificatore di processo. Il processo 0 è un processo speciale che viene creato all'avvio del sistema; dopo il fork di un processo figlio (processo 1), il processo 0 diventa il processo di scambio (a volte noto anche come " attività inattiva "). Il processo 1 , noto come init , è l'antenato di ogni altro processo nel sistema.

Linux

Nel kernel Linux , in cui c'è una differenza molto sottile tra processi e thread POSIX , ci sono due tipi di processi genitore, vale a dire genitore reale e genitore. Il genitore è il processo che riceve il segnale SIGCHLD alla terminazione del figlio, mentre il genitore reale è il thread che ha effettivamente creato questo processo figlio in un ambiente multithread. Per un processo normale, entrambi questi due valori sono uguali, ma per un thread POSIX che funge da processo, questi due valori potrebbero essere diversi.

Processi zombi

Il sistema operativo mantiene una tabella che associa ogni processo, tramite il suo identificatore di processo (generalmente denominato " pid ") ai dati necessari al suo funzionamento. Durante la vita di un processo, tali dati potrebbero includere segmenti di memoria designati per il processo, gli argomenti con cui è stato richiamato, variabili di ambiente , contatori sull'utilizzo delle risorse, ID utente, ID gruppo e set di gruppi e forse altri tipi di informazioni.

Quando un processo termina la sua esecuzione, o chiamando exit (anche se implicitamente, eseguendo un comando di ritorno dalla funzione principale ) o ricevendo un segnale che lo fa terminare bruscamente, il sistema operativo rilascia la maggior parte delle risorse e delle informazioni relative a quel processo, ma conserva ancora i dati sull'utilizzo delle risorse e il codice di stato di terminazione , perché un processo genitore potrebbe essere interessato a sapere se quel bambino è stato eseguito correttamente (utilizzando le funzioni standard per decodificare il codice di stato di terminazione) e la quantità di risorse di sistema consumato durante la sua esecuzione.

Per impostazione predefinita, il sistema presume che il processo genitore sia effettivamente interessato a tali informazioni al momento della cessazione del bambino, e quindi invia al genitore il segnale SIGCHLD per avvisare che ci sono alcuni dati su un bambino da raccogliere. Tale raccolta viene eseguita chiamando una funzione della famiglia wait (o wait stessa o uno dei suoi parenti, come waitpid , waitid o wait4 ). Non appena viene effettuata questa raccolta, il sistema rilascia gli ultimi bit di informazioni sul processo figlio e rimuove il suo pid dalla tabella dei processi. Tuttavia, se il processo genitore si sofferma a raccogliere i dati del bambino (o non riesce a farlo affatto), il sistema non ha altra scelta che mantenere i dati pid e terminazione del bambino nella tabella del processo a tempo indeterminato.

Tale processo terminato i cui dati non sono stati raccolti è chiamato processo zombie , o semplicemente zombie , nel gergo UNIX. Il nome è un'analogia umoristica dovuta al considerare il processo terminato come "non più vivo" o "morto" - dal momento che ha davvero cessato di funzionare - e un processo morto persistente ancora "incarnato" nel "mondo dei vivi" processi - il processo tabella, che è quindi in realtà "non morto" o "zombi".

I processi zombi potrebbero porre problemi su sistemi con risorse limitate o che hanno tabelle di processo di dimensioni limitate, poiché la creazione di nuovi processi attivi potrebbe essere impedita dalla mancanza di risorse ancora utilizzate dagli zombi di lunga durata.

È quindi una buona pratica di programmazione in qualsiasi programma che potrebbe generare processi figlio avere un codice per prevenire la formazione di zombi di lunga durata dai suoi figli originali. L'approccio più ovvio è avere codice che chiama wait o uno dei suoi parenti da qualche parte dopo aver creato un nuovo processo. Se si prevede che il programma crei molti processi figlio che possono essere eseguiti in modo asincrono e terminare in un ordine imprevedibile, è generalmente bene creare un gestore per il segnale SIGCHLD , chiamando una delle funzioni wait -family in un ciclo, fino a quando nessun figlio non raccolto i dati rimangono. È possibile che il processo genitore ignori completamente la terminazione dei suoi figli e ancora non crei zombi, ma ciò richiede la definizione esplicita di un gestore per SIGCHLD attraverso una chiamata alla firma con l'opzione speciale flag SA_NOCLDWAIT .

Processi orfani

I processi orfani sono una situazione opposta ai processi zombie, riferendosi al caso in cui un processo genitore termina prima dei suoi processi figli, che si dice diventino "orfani". A differenza della notifica asincrona da figlio a genitore che si verifica quando un processo figlio termina (tramite il segnale SIGCHLD ), i processi figli non vengono notificati immediatamente quando il loro genitore finisce. Invece, il sistema ridefinisce semplicemente il campo "PID genitore" nei dati del processo figlio per essere il processo che è l '"antenato" di ogni altro processo nel sistema, il cui PID ha generalmente il valore di 1 (uno), e il cui nome è tradizionalmente "init". Quindi, è stato detto che init "adotta" ogni processo orfano sul sistema.

Un presupposto piuttosto comune dai programmatori nuovi a UNIX era che i processi figli di un processo di terminazione saranno adottati dal processo genitore immediato di questo processo (da qui il "nonno" di quei processi figli). Tale supposizione era errata - a meno che, ovviamente, quel "nonno" non fosse l'init stesso.

Dopo il kernel 3.4 di Linux questo non è più vero, infatti i processi possono emettere la chiamata di sistema prctl () con l'opzione PR_SET_CHILD_SUBREAPER, e di conseguenza essi, non il processo # 1, diventeranno il genitore di uno qualsiasi dei loro processi discendenti orfani. Questo è il modo di lavorare dei moderni service manager e delle utilità di supervisione daemon, inclusi systemd, upstart e nosh service manager.

Questo è un abstract della pagina di manuale, che riporta che:

Un subreaper svolge il ruolo di init (1) per i suoi processi discendenti. Quando un processo diventa orfano (cioè, il suo genitore immediato termina), quel processo sarà riparato al subreaper antenato più vicino ancora in vita. Successivamente, le chiamate a getppid () nel processo orfano restituiranno ora il PID del processo subreaper, e quando l'orfano termina, è il processo subreaper che riceverà un segnale SIGCHLD e sarà in grado di attendere (2) sul processo per scoprire il suo stato di cessazione.

Riferimenti

Questo articolo si basa su materiale tratto dal Dizionario gratuito in linea di informatica prima del 1 ° novembre 2008 e incorporato sotto i termini di "rilascio della licenza " del GFDL , versione 1.3 o successiva.