2010-05-19 14 views
7

Se I fork un processo figlio e il processo figlio si chiude prima che il genitore chiama waitpid, le informazioni sullo stato di uscita impostate da waitpid sono ancora valide? Se è così, quando diventa non valido; cioè, come posso essere sicuro di poter chiamare waitpid sul pid figlio e continuare a ottenere informazioni sullo stato di uscita valide dopo un lasso di tempo arbitrario, e come faccio a "ripulire" (dire al sistema operativo che non sono più interessato al uscite informazioni sullo stato per il processo figlio finito)?Waitpid restituisce informazioni di stato valide per un processo figlio che è già stato chiuso?

Stavo giocando con il seguente codice, e sembra che le informazioni sullo stato di uscita siano valide almeno per alcuni secondi dopo che il bambino ha terminato, ma non so per quanto tempo o come informare il sistema operativo che non sarà chiamare waitpid ancora:

#include <assert.h> 
#include <pthread.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/wait.h> 

int main() 
{ 
    pid_t pid = fork(); 

    if (pid < 0) { 
     fprintf(stderr, "Failed to fork\n"); 
     return EXIT_FAILURE; 
    } 
    else if (pid == 0) { // code for child process 
     _exit(17); 
    } 
    else { // code for parent 
     sleep(3); 

     int status; 
     waitpid(pid, &status, 0); 
     waitpid(pid, &status, 0); // call `waitpid` again just to see if the first call had an effect 
     assert(WIFEXITED(status)); 
     assert(WEXITSTATUS(status) == 17); 
    } 

    return EXIT_SUCCESS; 
} 

risposta

10

Sì, waitpid funzionerà dopo che il bambino è uscito. Il SO manterrà la voce di un processo figlio nella tabella di processo (incluso lo stato di uscita) finché il genitore non chiama waitpid (o un'altra funzione wait -family) o fino a quando il genitore non esce (a quel punto lo stato viene raccolto dal processo init) . Questo è ciò che un processo "zombie" è: un processo che è uscito da è ancora residente nella tabella di processo esattamente per questo scopo.

Il processo 'voce nella tabella dovrebbe andare via dopo la prima chiamata a waitpid. Sospetto il motivo per cui nel tuo esempio sembra che tu sia in grado di chiamare lo waitpid due volte semplicemente perché waitpid non modificherà l'argomento status se pid non esiste più. Quindi la prima chiamata dovrebbe funzionare e compilare status e la seconda chiamata dovrebbe restituire un codice di errore e non cambiare status. È possibile verificare ciò ispezionando i valori di ritorno delle chiamate waitpid e/o utilizzando due diverse variabili status.

+0

In effetti, la seconda chiamata 'waitpid' non è riuscita. Non ci ho pensato! Grazie per averlo indicato. –

3

Il sistema operativo continua a processo terminato in un zombie state fino alla sua madre (che potrebbe essere il init se il processo padre originale terminato prima) raccoglie che stato di uscita con wait(2) chiamata di sistema. Quindi la risposta è: lo stato di uscita del processo non diventa valido.

2

Sì.

Dal man page:

Un figlio che termina, ma non è stato aspettato diventa uno "zombie". Il kernel mantiene un insieme minimo di informazioni sul processo di zombie (PID, stato di terminazione, informazioni sulle risorse utilizzo) al fine di consentire il genitore per eseguire successivamente un'attesa a ottenere informazioni sul bambino.

Problemi correlati