Quelle est la différence entre les divers $SIG{CHLD} valeurs?
Quelle est la différence entre ces paramètres?
$SIG{CHLD} = 'IGNORE'
$SIG{CHLD} = 'DEFAULT'
$SIG{CHLD} = ''
$SIG{CHLD} = undef
Selon "Advanced Programming in the UNIX Environment, 2e édition", la figure 10.1 la valeur par défaut de SIGCHLD est "ignorer".
Si "ignorer" signifiait "SIG_IGN", alors aucun enfant ne pourrait jamais être un zombie, et ce n'est pas le cas.
Il n'est pas beaucoup plus clair à partir de là:
Si le processus définit sa disposition à SIG_IGN, les enfants
le processus appelant ne générera pas de zombie processus. Notez que
ceci est différent de son action par défaut (SIG_DFL), qui, à partir de la Figure
10.1 est d'être ignoré. Au lieu de cela, en cas de résiliation, le statut de ces processus enfants
est mis au rebut.
Je vais avoir un moment difficile groking quel est l'impact de différentes valeurs (ou indéfini à non-valeur). Jusqu'à présent, la solution a été de tourner à travers ces choix jusqu'à ce que je obtenir le comportement désiré, et je préfère comprendre exactement comment chaque valeur définit le comportement du signal.
Le comportement: un processus enfant appelle "système" ou à l'aide de backticks qui créer un autre enfant, et le signal normalement être pris par le mal (parent) gestionnaire. Définition d'un gestionnaire local peut fonctionner, mais je ne comprends pas de quelle valeur est la plus appropriée si je veux le signal de la grand-enfant de ne rien faire.
Quelqu'un pourrait-il svp m'éclairer?
Mise à JOUR:
Basé sur ikegami commentaires, j'ai fait quelques tests spécifiques. Le comportement est, au moins partiellement, la plate-forme.
Considérer le fragment suivant:
$SIG{CHLD} = sub {
while( ( my $child = waitpid( -1, &WNOHANG ) ) > 0 ) {
print "SIGNAL CHLD $child\n";
}
};
my $pid = fork();
if( ! $pid ) {
system( 'echo Grandchild PID = $$' );
sleep 2;
exit;
}
print "Child PID = $pid\n";
sleep 5;
Perl 5.8.6 sur Solaris 10 affiche "SIGNAL CHLD" messages pour le PID de l'appel system (). Faire quoi que ce soit, même d'aussi insignifiant qu'
local $SIG{CHLD};
dans l'enfant va supprimer ces messages.
Sur tous les autres saveur, j'ai essayé, la faucheuse ne voit jamais l'enfant.
local $SIG{CHLD};
est le même que local $SIG{CHLD} = undef;
OriginalL'auteur Trueblood | 2011-12-05
Vous devez vous connecter pour publier un commentaire.
Voir
%SIG
.$SIG{CHLD} = 'IGNORE';
les causes de votre processus d'ignorer SIGCHLD signaux.$SIG{CHLD} = 'DEFAULT';
les causes de votre processus pour traiter SIGCHLD signaux comme il le ferait si vous n'aviez pas gâché avec$SIG{CHLD}
ou l'é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.Comme pour la moisson, les enfants d'un parent dont l'SIGCHLD gestionnaire est pas explicitement définie à
IGNORE
continuera automatiquement par le système dès qu'il la quitte.''
etundef
sont des valeurs valides et ils DWIM, comme le faitdelete $SIG{CHLD}
.Vous dites
undef
ensembles d'IGNORER et dedelete
définit par DÉFAUT? Pourtant, cela ne les rend pas valide. À partir de ce que vous avez dit dans votre solution, il semble comme il n'y a tout simplement un manque de vérification des erreurs à l'heure actuelle (depuis l'utilisation deIGNORED
ne faitDEFAULT
).Ils sont tous indiscernables de l'affectation de
$SIG{CHLD}='DEFAULT'
. Ils sont valables dans le sens où ils ne se cassent pas le code ou des avertissements -- je ne veux pas dire par là que ces constructions font partie de la Perl spec. Une future mise en œuvre peut interdire ou décourager ces missions ou à proscrire un sens totalement différent.OriginalL'auteur ikegami
Il y a deux manières d'éviter la création de zombie processus:
$SIG{CHLD}='IGNORE'
wait
ouwaitpid
appels (ce qui pourrait être fait à l'intérieur d'un SIGCHLD gestionnaire, mais il n'a pas besoin d'être)Réglage
$SIG{CHLD}='IGNORE'
les pièges de la SIGCHLD à niveau du système d'exploitation, le nettoyage le processus de l'enfant, sans même la signalisation de votre programme Perl.Tout autre réglage, y compris
'DEFAULT'
,undef
,""
,sub {}
,'some_function_name_that_doesnt_even_exist'
va provoquer le signal pour être livré à Perl, et l'enfant ne sera pas récolté automatiquement.En cumulant le processus vous-même avec
wait
etwaitpid
, vous pouvez obtenir des informations supplémentaires comme le statut de sortie de l'enfant du processus, et (plus ou moins) l'ordre dans lequel l'enfant processus terminé. Si$SIG{CHLD}
est fixé à'IGNORE'
,wait
etwaitpid
toujours renvoient -1 et de ne pas définir$?
.La
SIGCHLD
, le cas échéant, est systématiquement remis au processus qui a engendré le processus de l'enfant, donc je ne pense pas que vous avez raison de dire qu'unSIGCHLD
à partir d'un petit-enfant de processus (à partir d'unsystem
appel à un processus enfant) est pris dans le processus parent. Probablement ce qui se passe, c'est que votre enfant hérite du gestionnaire de signal à partir de son processus parent.system
et backticks va (sur la plupart des systèmes) générer unSIGCHLD
sur l'achèvement et le$?
valeur avec la commande de sortie du statut. Mais Perl va récolter ces sous-processus lui-même, et vous ne serez pas en mesure de capturer l'id de processus d'unsystem
ou backticks appel avecwait
ouwaitpid
.OriginalL'auteur mob
Il y a deux sens différent pour les "ignorer", et ils se produisent à deux points différents de l'évaluation.
La première utilisation des préoccupations s'il faut envoyer le signal à tous. Quand un enfant de processus des sorties, il est généralement occupé par le système d'exploitation et un CHLD signal est envoyé à sa mère. Lors de la configuration de $SIG{CHLD} 'IGNORER', il indique au système de ne pas générer un signal à tous les et de laisser le processus de l'enfant à la sortie. Le parent n'a pas de possibilité d'obtenir de l'information sur le processus de l'enfant, et pas de zombies résultat.
Mais si $SIG{CHLD} est rien d'autre que 'IGNORER', cela signifie délivrer le signal au processus parent, à quel point il y a une coutume gestionnaire de signal ou par défaut un gestionnaire de signal, et le gestionnaire par défaut varient en fonction de différents systèmes ou même des versions du même système d'exploitation. Le livre et le signal(7) page de man de parler de ce qui se passe par défaut si un signal est délivré au processus parent (c'est à dire gestionnaire n'est pas réglé sur 'IGNORE'). Donc la deuxième utilisation de l'ignorer est liée à ce qui action à prendre pour la livraison du signal. Par exemple SIGINT sera la cause de votre processus de résiliation, et SIGSTOP sera la cause de votre processus de "pause", même si, la coutume les gestionnaires de signaux de changement de ces actions par défaut.
Pour la SIGCHLD, la valeur par défaut est sur "ignorer", mais dans ce utilisation, il veut simplement dire que l' (parent) ne continue à exécuter normalement tout le processus de l'enfant attend (c'est à dire pas de résiliation ou l'abandon du processus parent). Vous pouvez ensuite wait() par la suite pour obtenir des informations et d'éviter un zombie.
OriginalL'auteur simpleuser
Transmis à l'OS comme SIG_IGN, qui, selon le système d'exploitation docs, rend l'enfant procédés de mettre fin à devenir des zombies (ou des rapports de leur code de sortie pour le parent).
Ce sont tous les mêmes au niveau de l'OS (ils vont le signal d'appel() avec SIG_DFL). Cependant, certains paquets perl, notamment AnyEvent::enfant, ne fonctionne pas quand $SIG{CHLD} est définie sur "par DÉFAUT".
OriginalL'auteur Steven Schoch