8
votes

Quelle est la différence entre divers $ SIG {CHLD} valeurs?

Quelle est la différence entre ces paramètres? XXX

Selon "Programmation avancée dans l'environnement UNIX, 2e édition", Figure 10.1 La valeur par défaut de Sigchld est "Ignorer"

Si "Ignorer" signifiait "Sig_ign", aucun enfant ne serait jamais un zombie, et ce n'est pas le cas.

Il ne s'agit pas beaucoup plus clair de là:

Si le processus définit spécifiquement sa disposition à SIG_ign, enfants du processus d'appel ne générera pas de processus zombies. Noter que Ceci est différent de son action par défaut (SIG_DFL), qui de la figure 10.1 doit être ignoré. Au lieu de cela, sur la résiliation, le statut de ces processus enfants est jeté.

J'ai du mal à groker quel est l'impact des différentes valeurs (ou une non-valeur non définie). Jusqu'à présent, la solution a été de tourner à travers ces choix jusqu'à ce que je reçoive le comportement souhaité et je préfère comprendre exactement comment chaque valeur définit le comportement du signal.

Le comportement: un processus d'enfant est appeler "système" ou utiliser des backticks qui créent un autre enfant et que le signal serait normalement capturé par le mauvais gestionnaire (parent). La définition d'un gestionnaire local peut fonctionner, mais je ne comprends pas quelle valeur est la plus appropriée si je veux le signal du grand-enfant de ne rien faire.

Quelqu'un pourrait-il vous éclairer? < p> mise à jour: Basé sur les commentaires d'Ikegami, j'ai fait des tests spécifiques. Le comportement est, au moins partiellement, spécifique à la plate-forme.

considère le fragment suivant: xxx

perl 5.8.6 sur Solaris 10 affichera "Signal Chld "Messages pour le PID de l'appel système (). Faire n'importe quoi, même aussi trivial que

SIG $ local {CHLD};

chez l'enfant supprimera ces messages.

sur toutes les autres saveurs que j'ai essayées, la faucheuse ne voit jamais l'enfant.


1 commentaires

local $ SIG {CHLD}; est identique à SIG {chld} = UNDF;


4 Réponses :


13
votes

Il y a deux façons d'éviter de créer des processus zombies:

  1. définir explicitement $ sig {chld} = 'ignorer'
  2. récolte les enfants morts expliquellement avec le attendre ou appelé appels (cela pourrait être fait à l'intérieur d'un gestionnaire Sigchld, mais il n'est pas nécessaire de ne pas être)

    Réglage $ SIG {CHLD} = 'Ignorer' piège le SIGCHLD au niveau du système d'exploitation, nettoyant le processus enfant sans même signaler votre programme PERL.

    Tout autre paramètre, y compris 'par défaut' , undef , "" , sous {} , < Code> 'Certain_function_name_that_doesnt_even_exist' entraînera la livraison du signal à Perl, et l'enfant ne sera pas récolté automatiquement.

    en récolérant le processus vous-même avec attendre et waiterpid , vous pouvez obtenir des informations supplémentaires telles que l'état de sortie du processus enfant et (plus ou moins). ordre dans lequel l'enfant traite fini. Si $ SIG {CHLD} est défini sur 'Ignorer' , wait et waiterpid toujours retour -1 et don 't set $? .

    Le sigchld , le cas échéant, est toujours livré au processus qui a engendré le processus enfant, je ne pense donc pas que vous avez raison de dire qu'un sigchld de Un processus de petit-enfant (à partir d'un système appel dans un processus enfant) est pris dans le processus parent. Probablement ce qui se passe est que votre processus enfant hérite du gestionnaire de signal de son processus parent.

    système et backticks (sur la plupart des systèmes) génère un sigchld à la fin et définira la valeur $? avec l'état de sortie de la commande . Mais Perl récoltera ces sous-processus lui-même, et vous ne serez pas en mesure de capturer l'ID de processus d'un appel ou d'appel de backticks avec attendre ou waiterpid .


1 commentaires

3. récolter les enfants morts implicitement en sortant.



11
votes

voir % SIG .

$ SIG {CHLD} = 'Ignorer'; provoque l'ignorer les signaux SIGCHLD.

$ SIG {CHLD} = 'Par défaut'; Causes Votre processus pour traiter les signaux SIGCHLD, car il ne vous aurait pas été gâché avec $ SIG {CHLD} ou équivalent. Selon Kill (1), un processus sur mon système ignore Sigchld par défaut

$ SIG {CHLD} = ''; et $ SIG {CHLD} = Undef ; ne sont pas des valeurs valides.

Quant à la récolte, les enfants d'un parent dont le gestionnaire Sigchld est défini explicitement sur Ignorer sera automatiquement récolté par le système dès que le système dès que Il sort. xxx


3 commentaires

'' ' et UNDEF sont des valeurs valides et ils se dressent, de même que Supprimer $ SIG {CHLD} .


@mob, es-tu dites UNDEF SETS POUR IGNORE ET Supprimer Définit par défaut? Néanmoins, cela ne les rend pas valide. D'après ce que vous avez dit dans votre solution, il semble qu'il y ait simplement un manque de vérification des erreurs à l'heure actuelle (depuis l'utilisation de ignoré réellement par défaut ).


Ils sont tous indiscernables d'attribuer $ SIG {CHLD} = 'Par défaut' . Ils sont valables en ce sens qu'ils ne cassent pas le code ni les avertissements émettent des avertissements - je ne voulais pas suggérer que ces constructions font partie de la spécification PERL. Une future mise en œuvre peut interdire ou décourager ces missions, ou proscrire un sens totalement différent pour eux.



2
votes

Il existe deux signification différente pour "ignorer", et ils se produisent à deux points d'évaluation différents.

La première utilisation concerne de délivrer le signal du tout. Lorsqu'un enfant traite des sorties, il est généralement détenu par le système d'exploitation et un signal CHLD est envoyé à son parent. Lors de la définition $ SIG {CHLD} sur 'Ignorer', il indique au système de ne pas générer de signal du tout et de laisser simplement le processus d'enfant. Le parent n'a aucune occasion d'obtenir des informations sur le processus d'enfant et aucun résultat de zombies.

Mais si $ SIG {CHLD} est autre chose que «ignorer», cela signifie de délivrer le signal au processus parent, auquel il existe un gestionnaire de signal personnalisé ou un gestionnaire de signal par défaut, et le gestionnaire par défaut sera varier sur différents systèmes ou même des versions du même système d'exploitation. La page du livre et du signal (7) Manque de ce qui se passe par défaut si un signal est livré au processus parent (c'est-à-dire que le gestionnaire n'est pas défini sur "Ignorer"). Donc La seconde utilisation de l'ignore est liée à laquelle action à prendre pour un signal livré . Par exemple, SIGINT entraînera la résiliation de votre processus et SIGSTOP entraînera votre processus de "pause", bien que les gestionnaires de signal personnalisés changent ces actions par défaut.

pour le signal SIGCHLD, la valeur par défaut est de "ignorer", mais dans cette utilisation Cela signifie simplement que le processus (parent) continue de continuer à exécuter normalement pendant que le processus d'enfant attend (c'est-à-dire aucune résiliation ou abandon du processus parent). Vous pouvez ensuite attendre () dessus plus tard pour que ce soit des informations et d'éviter un zombie.


0 commentaires

1
votes

$ SIG {CHLD} = 'ignorer'

Ceci est transmis au système d'exploitation comme Sig_ign, qui, selon la DOCS du système d'exploitation, rend les processus enfants terminés sans devenir des zombies (ou signaler leur code de sortie au parent).

$ SIG {CHLD} = 'Par défaut'
$ SIG {CHLD} = ''
$ SIG {CHLD} = UNDEF

Ceux-ci sont tous identiques au niveau du système d'exploitation (ils appelleront le signal () avec SIG_DFL). Cependant, certains paquets Perl, notamment Anyevent :: Child, ne fonctionneront pas lorsque $ SIG {CHLD} est défini sur "Par défaut".


2 commentaires

Voulez-vous dire "sans" se terminer par devenir "


Oui merci. (Je traversais très ancien email.)