2017-10-07 19 views
0

Lorsqu'un processus enfant dérivé d'un parent meurt, il existe toujours dans une certaine mesure et reste dans un état zombie, jusqu'à ce qu'il soit extrait d'un appel wait().Détacher le processus enfant du parent

Est-il possible de détacher cette relation parent-enfant et de faire en sorte que les enfants soient automatiquement récoltés? Peut-être orphelin de l'enfant à init, ou quelque chose? Cas d'utilisation possible: Créer un grand nombre de processus ignifuges dans un programme de longue durée sans «conserver» une liste croissante de PID zombies qui ne peuvent pas être recyclés par le système d'exploitation.

Répondre

1

par the POSIX _exit() documentation:

Si le processus parent du processus d'appel a mis son SA_NOCLDWAIT drapeau ou a mis l'action pour le signal SIGCHLD à SIG_IGN:

  • Le processus les informations d'état (voir Informations d'état), le cas échéant, doivent être ignorées.

  • La durée de vie du processus appelant doit se terminer immédiatement. Si SA_NOCLDWAIT est défini, la mise en œuvre est définie si un signal SIGCHLD est envoyé au processus parent.

  • Si un thread dans le processus parent du processus d'appel est bloqué dans wait(), waitpid() ou waitid(), et le processus parent n'a pas de processus enfant reste dans l'ensemble des attendu-pour les enfants, le wait(), waitid() ou waitpid() doit échouer et définir errno à [ECHILD].

Sinon:

  • informations d'état (voir les informations d'état) sont produits.

  • Le processus appelant doit être transformé en un processus zombie. Ses informations d'état doivent être mises à la disposition du processus parent jusqu'à la fin de la durée de vie du processus.

  • ...

En bref, pour éviter les processus de l'enfant de devenir processus zombie, la façon la plus simple est d'appeler sigignore(SIGCHLD);

MISE À JOUR

qui ne l'impact la possibilité d'attendre tout processus enfant, ce qui peut ne pas être désiré.Le setsid() library function permet un processus de se dissocier de son parent:

pid_t child = fork(); 
if ((pid_t) 0 == child) 
{ 
    int rc = setsid(); 

    rc = execv(...); 
} 
else ... 

Le processus enfant dissociées ne crée pas un zombie, ni envoyer SIGCHLD au processus parent sur mon instance installée de Solaris 11.2.

Il s'agit d'une démonétisation abrégée d'un processus enfant "fire-and-forget", ne faisant que ce qui est nécessaire pour empêcher la création d'un zombie ou envoyer SIGCHLD au processus parent. Pour une procédure de démonétisation beaucoup plus complète, voir Linux daemonize

+0

Merci, connaissez-vous une solution qui ne change pas le comportement global d'un programme? Cette solution va changer d'autres parties du programme qui ne voudront pas se synchroniser avec leurs enfants. – Shaggi

+0

@Shaggi Voir la mise à jour. Vous devriez pouvoir utiliser 'setsid()' après 'fork()' et avant 'execv *()' pour permettre au processus fils de se "cacher" du parent, et ne pas créer un zombie ni envoyer 'SIGCHLD' à la résiliation . –

+0

Très bien, merci. Mon dernier souhait est d'être capable de le faire du parent à un stade arbitraire dans la vie de l'enfant, mais je suppose que ce n'est pas vraiment possible. – Shaggi