2010-05-19 17 views
7

Si yo fork es un proceso hijo, y el proceso hijo sale antes de que el padre llame al waitpid, ¿sigue siendo válida la información de estado de salida establecida en waitpid? Si es así, ¿cuándo se vuelve inválido? es decir, cómo me aseguro de que puedo llamar al waitpid en el pid niño y continuar obteniendo información de estado de salida válida después de un período de tiempo arbitrario, y cómo puedo "limpiar" (decirle al SO que ya no estoy interesado en el información de estado de salida para el proceso hijo terminado)?¿waitpid arroja información de estado válida para un proceso hijo que ya ha salido?

Estaba jugando con el siguiente código, y parece que la información de estado de salida es válida durante al menos unos segundos después de que el niño termine, pero no sé por cuánto tiempo o cómo informar al sistema operativo que no se llama de nuevo waitpid:

#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; 
} 

Respuesta

10

Sí, waitpid va a funcionar después de que el niño haya salido. El sistema operativo mantendrá una entrada de proceso secundario en la tabla de proceso (incluido el estado de salida) hasta que el padre llame al waitpid (u otra wait -función de la familia) o hasta que el padre salga (en ese punto se recopila el estado mediante el proceso init) . Esto es lo que es un proceso "zombie": un proceso que ha salido por es todavía residente en la mesa de proceso para exactamente este propósito.

La entrada del proceso en la tabla debe desaparecer después de la primera llamada al waitpid. Sospecho que la razón por la que en su ejemplo parece que puede llamar al waitpid dos veces es simplemente porque waitpid no modificará el argumento status si pid ya no existe. Por lo tanto, la primera llamada debería estar funcionando y cumplimentando status, y la segunda llamada debería devolver un código de error y no cambiar status. Puede verificar esto inspeccionando los valores de retorno de las llamadas waitpid y/o usando dos variables diferentes status.

+0

De hecho, la segunda llamada 'waitpid' falló. ¡No pensé en eso! Gracias por señalar esto. –

3

El sistema operativo finaliza el proceso en zombie state hasta que su elemento principal (que podría ser init si el proceso principal original finalizó antes) recopila ese estado de salida con la llamada al sistema wait(2). Entonces la respuesta es: el estado de salida del proceso no se vuelve inválido.

2

Sí.

Desde el man page:

Un niño que termina, pero no ha sido esperado se convierte en un "zombi". El núcleo mantiene un conjunto mínimo de información sobre el proceso zombi (PID, estado de terminación, el uso de información de recursos ) con el fin de permitir que los padres para llevar a cabo después de una espera de obtener información sobre el niño.

Cuestiones relacionadas