¿El waitpid producir información de estado válida para un proceso hijo que ya ha salido?
Pregunta
Si fork
un proceso hijo, y el proceso finalice niño antes de la waitpid
llamadas de padres, a continuación, es la información sobre el estado de salida que se establece por waitpid
sigue siendo válido? Si es así, ¿cuándo se vuelve válida; es decir, ¿cómo puedo garantizar que puedo llamar waitpid
en el pid del niño y continuar recibiendo información de estado de salida válida después de una cantidad arbitraria de tiempo, y cómo puedo "la limpieza" (decirle al sistema operativo que ya no estoy interesado en el información de estado de salida para el proceso hijo terminado)?
Yo estaba jugando con el siguiente código, y parece que la información de estado de salida es válido durante al menos unos segundos después de que finalice niño, pero no sé por cuánto tiempo o cómo informar al sistema operativo que he ganado 't estar llamando waitpid
nuevo:
#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;
}
Solución
Sí, waitpid
funcionará después de que el hijo ha terminado. El sistema operativo se mantendrá la entrada de un proceso hijo en la tabla de procesos (incluyendo el código de salida) alrededor hasta que el padre llama waitpid
(u otra función wait
familiar) o hasta que las salidas de los padres (momento en el que el estado es recogido por el proceso de init
) . Esto es lo que un proceso "zombie" es:. Un proceso que ha salido por sigue siendo residente en la tabla de procesos precisamente para este propósito
La entrada de proceso en la tabla debe desaparecer después de la primera llamada a waitpid
. Sospecho que la razón de que en su ejemplo que parece ser capaz de llamar a waitpid
dos veces es simplemente porque waitpid
no modificará el argumento status
si pid
ya no existe. Así que la primera llamada debería estar trabajando y rellenando status
, y la segunda llamada debe devolver un código de error y no cambiar status
. Esto se puede comprobar mediante la inspección de los valores de retorno de las llamadas waitpid
y / o el uso de dos variables status
diferentes.
Otros consejos
El sistema operativo mantiene proceso terminado en un zombi estado hasta que su padre (que podría ser el init
si el proceso padre original de terminar antes) recoge que el código de salida con la llamada al sistema wait(2)
. Así que la respuesta es -. El estado de salida del proceso no se convierte en no válido
Sí.
Desde el página del manual :
Un niño que termina, pero no tiene ha esperado a que 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, los recursos información de uso) con el fin de permitir los padres para llevar a cabo más adelante una espera para obtener información sobre el niño.