Le suivi de la mort d'un enfant de processus
Comment ai-je pu traquer la mort d'un enfant sans rendre le processus parent attendre jusqu'à ce que le processus de l'enfant a été tué?
Je suis en train d'essayer un scénario client-serveur où le serveur accepte la connexion d'un client et les fourches d'un nouveau processus pour chaque connexion, il accepte.
Je suis ignorant SIGCHLD signaux pour prévenir zombie création.
signal(SIGCHLD, SIG_IGN);
while(1)
{
accept();
clients++;
if(fork() ==0)
{
childfunction();
clients--;
}
else
{
}
}
Le problème dans le scénario ci-dessus est que si l'enfant est tué dans la childfunction()
fonction, la variable globale clients
n'est pas décrémenté.
REMARQUE: je suis à la recherche d'une solution sans l'aide de SIGCHLD ... Si possible
- Vous pouvez faire quelque chose dans le gestionnaire de signal de SIGCHLD
- Je l'ai déjà mentionné ... SIGCHLD est ignoré .. ?
- +1 pour un incroyablement spectaculaire titre et la phrase d'ouverture. D:
Vous devez vous connecter pour publier un commentaire.
En général, vous écrivez un gestionnaire pour
SIGCHLD
qui appellewaitpid()
sur pid-1
. Vous pouvez utiliser la valeur de retour de la afin de déterminer ce qui pid est mort. Par exemple:Alternativement, vous pouvez appeler
waitpid(pid, &status, 0)
avec l'enfant de l'ID de processus spécifié, et de façon synchrone attendre de mourir. Ou utiliserWNOHANG
pour vérifier son état sans blocage.waitpid()
la "zombie" s'en va.SIGCHLD
signal pour.if
dans votrechld_handler
doit être unwhile ((p = waitpid(-1, &status, WNOHANG)) > 0)
(Parce que si deux enfants ou plus quitter rapidement dans la succession, vous pouvez seulement obtenir un signal).Aucune des solutions de mesure d'offrir une approche sans l'aide de SIGCHLD que la question des demandes. Voici une mise en œuvre d'une approche alternative à l'aide de sondage comme indiqué dans cette réponse (ce qui explique aussi pourquoi vous devriez éviter d'utiliser des SIGCHLD dans des situations de ce genre):
(Note: j'ai omis un certain nombre de meilleures pratiques comme l'erreur de vérification et de nettoyage des descripteurs de fichiers pour des raisons de concision)
Et voici un exemple de sortie de l'exécution du programme avec la
printf
déclarations sans commentaire:Vous ne voulez pas un zombie. Si un enfant meurt et la mère est toujours en cours d'EXÉCUTION mais ne publie jamais un
wait()
/waitpid()
appel à la récolte de l'état, le système ne permet pas de libérer les ressources associées à l'enfant et un zombie/défunte processus est à gauche dans la procédure de la table.Essayez de changer votre
SIGCHLD
gestionnaire de quelque chose de plus proche de la suivante:Vous pouvez éventuellement masque/bloc supplémentaire
SIGCHLD
signaux au cours de l'exécution du gestionnaire de signal à l'aide desigprocmask()
. L'bloqué masque doit être retourné à sa valeur d'origine lorsque le signal de la routine de traitement est terminé.Si vraiment vous ne voulez pas utiliser un
SIGCHLD
gestionnaire, vous pourriez essayer d'ajouter de l'enfant boucle de traitement dans un endroit où il serait appelé régulièrement des sondages et d'anciens enfants.La variable des "clients" sont dans les différents espaces d'adressage processus après le fork() et quand vous décrémenter la variable de l'enfant, cela n'affectera pas la valeur du parent. Je pense que vous avez besoin pour gérer SIGCHLD à gérer le comte correctement.