2011-04-03 3 views
2
void childSignalHandler(int signo) { 
    int status; 

    pid_t pid = wait(&status); 

    struct PIDList* record = getRecordForPID(childlist, pid); 
    if (record != NULL) 
     record->returnValue = status; 
} 

question rapide:Manipulation SIGCHLD, comment enregistrer les valeurs de retour des enfants car ils meurent

Je veux que ce gestionnaire, quand un enfant meurt (cette application engendre beaucoup d'enfants), obtenir leur valeur de retour et l'enregistrer (trois dernières lignes). Est-ce que ça va le faire, ou est-ce que je me trompe?

Nous vous remercions de votre temps!

(également, la terminologie API linux est effrayant comme l'enfer, vérifier pour les enfants qui meurent et ainsi de suite)

Répondre

4

Cela devrait faire le travail, si vous définissez votre fonction en tant que gestionnaire pour SIGCHLD.

Cependant, SIGCHLD peut être envoyé au processus parent non seulement après la sortie de l'enfant. Certains autres événements sont également signalés de cette manière (par exemple, lorsque l'enfant est arrêté). Voir man wait(3) pour une explication détaillée.

+0

Merci, mate. ':)' –

4

Les signaux de note ne sont pas mis en file d'attente. Si deux enfants meurent rapidement l'un après l'autre, vous ne pouvez en recevoir qu'un seul SIGCHLD. Donc, vous devriez boucler en appelant waitpid() jusqu'à ce qu'il n'y ait plus de processus à gérer:

int status; 
pid_t pid; 

while ((pid = waitpid(-1, &status, WNOHANG)) > 0) { 
    if (WIFEXITED(status)) { 
     struct PIDList *record = getRecordForPID(childlist, pid); 

     if (record != NULL) 
      record->returnValue = WEXITSTATUS(status); 
    } 
} 
+2

Notez que sur les systèmes modernes, 'SIGCHLD' est mis en file d'attente, mais le code dans la question est toujours faux car il n'y a aucune garantie que' wait() 'retournera le pid de l'instance actuelle de' SIGCHLD' . Lorsque 'wait()' ou une fonction similaire signale l'état d'un processus fils, le signal 'SIGCHLD' correspondant, s'il existe, est considéré comme accepté et le gestionnaire de signal ne sera pas appelé. – jilles

+0

@jilles J'ai également observé ce comportement: '" le signal SIGCHLD correspondant, le cas échéant, est considéré comme accepté et le gestionnaire de signal ne sera pas appelé "' (happy debugging time ...). Comme je ne savais pas si mon application se comportait correctement, je suis heureux d'avoir trouvé votre commentaire à ce sujet maintenant. Je suis toujours à la recherche d'une référence officielle. –

+0

@jilles C'est ça, n'est-ce pas? Si _POSIX_REALTIME_SIGNALS est défini et que l'implémentation place le signal SIGCHLD en file d'attente, si wait() ou waitpid() renvoie le statut d'un processus enfant, tout signal SIGCHLD en attente associé à l'ID du processus enfant doit être ignoré 'de http://linux.die.net/man/3/waitpid –

Questions connexes