2010-05-19 12 views
7

Si fork un processus enfant et le processus enfant se termine avant que le parent appelle waitpid, les informations d'état de sortie définies par waitpid sont-elles toujours valides? Si oui, quand cela devient-il invalide? Par exemple, comment puis-je m'assurer que je peux appeler waitpid sur le PID enfant et continuer à obtenir des informations d'état de sortie valides après un laps de temps arbitraire, et comment puis-je "nettoyer" (dire au système d'exploitation que je ne suis plus intéressé par informations d'état de sortie pour le processus fils fini)? Je jouais avec le code suivant, et il semble que l'information de statut de sortie est valide pendant au moins quelques secondes après la fin de l'enfant, mais je ne sais pas pour combien de temps ou comment informer l'OS que je ne sera pas appeler à nouveau waitpid:waitpid fournit-il des informations d'état valides pour un processus enfant qui a déjà quitté?

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

Répondre

10

Oui, waitpid fonctionnera après que l'enfant a quitté. Le système d'exploitation gardera une entrée de processus enfant dans la table de processus (y compris le statut de sortie) jusqu'à ce que le parent appelle waitpid (ou une autre fonction wait -family) ou jusqu'à la sortie du parent (à quel point le statut est collecté par le processus init) . C'est ce qu'un processus "zombie" est: un processus qui a quitté est toujours résident dans la table de processus dans ce but précis.

L'entrée du processus dans la table devrait disparaître après le premier appel à waitpid. Je soupçonne la raison que dans votre exemple, vous semblez pouvoir appeler waitpid deux fois est simplement parce que waitpid ne modifiera pas l'argument status si pid n'existe plus. Donc, le premier appel devrait fonctionner et remplir status, et le second appel devrait renvoyer un code d'erreur et ne pas changer status. Vous pouvez vérifier cela en inspectant les valeurs de retour des appels waitpid et/ou en utilisant deux variables status différentes.

+0

En effet, le deuxième appel 'waitpid' a échoué. Je n'y ai pas pensé! Merci d'avoir signalé cela. –

3

Le système d'exploitation maintient processus terminé dans un zombie state jusqu'à ce que son parent (qui pourrait être le init si le processus parent d'origine mis fin plus tôt) que le statut de collecte avec la sortie wait(2) appel système. Donc, la réponse est - le statut de sortie du processus ne devient pas invalide.

2

Oui.

De l'man page:

Un enfant qui se termine, mais n'a pas été attendu devient un "zombie". Le noyau maintient un ensemble minimal de informations sur le processus zombie (PID, état de cessation d'emploi, informations sur l'utilisation des ressources ) afin de permettre le parent d'effectuer plus tard, une attente pour obtenir des informations sur l'enfant.