gestion des signaux
Le
Benoit Izac
Bonjour,
J'ai un petit problème avec la gestions de signaux en Perl. J'ai écrit
un petit script qui ressemble à ça :
while (1) {
$pid = fork;
if (not defined $pid) {
# erreur
} elsif ($pid == 0) {
une_tache;
} else {
sleep 5;
}
}
Jusqu'ici, ça marche bien. Je souhaite rajouter un petit plus en envoyant
un signal et faire autre chose, ça ressemble à ça :
# TSTP est reçu lorsque je tape ^Z
$SIG{TSTP} = sub { autre_tache; };
# même programme que ci-dessus
autre_tache s'exécute bien lorsque je tape ^Z mais le problème c'est que
une_tache s'exécute aussi. Comment faire en sorte que ^Z puisse juste
exécuter autre_tache sans interférer sur le reste du programme ?
Merci.
--
Benoit Izac
J'ai un petit problème avec la gestions de signaux en Perl. J'ai écrit
un petit script qui ressemble à ça :
while (1) {
$pid = fork;
if (not defined $pid) {
# erreur
} elsif ($pid == 0) {
une_tache;
} else {
sleep 5;
}
}
Jusqu'ici, ça marche bien. Je souhaite rajouter un petit plus en envoyant
un signal et faire autre chose, ça ressemble à ça :
# TSTP est reçu lorsque je tape ^Z
$SIG{TSTP} = sub { autre_tache; };
# même programme que ci-dessus
autre_tache s'exécute bien lorsque je tape ^Z mais le problème c'est que
une_tache s'exécute aussi. Comment faire en sorte que ^Z puisse juste
exécuter autre_tache sans interférer sur le reste du programme ?
Merci.
--
Benoit Izac

Poser une question


Je ne comprend pas du tout ce que tu essaies de faire, exemple trop simplifie
je crains.
Que ton signal interrompe sleep, c'est parfaitement normal et attendu.
En plus, tu as un fork qui traine. Ca complique encore un peu, vu que tous
les process vont voir le ^Z.
le 15/04/2010 à 00:38, Marc Espie a écrit dans le message
Un exemple concret :
% cat test.pl
#!/usr/bin/perl
use strict;
use warnings;
$SIG{TSTP} = sub { print "signal receivedn"; };
while (1) {
my $pid = fork;
if (not defined $pid) {
die "fork failed";
} elsif ($pid eq 0) {
print time . "n";
exit;
} else {
sleep 5;
}
}
% perl test.pl
1271286741
1271286746
^Zsignal received
1271286747
^Zsignal received
1271286748
^C
%
Si je remplace
$SIG{TSTP} = sub { print "signal receivedn"; };
par
$SIG{TSTP} = 'IGNORE';
^Z n'a aucun effet. Ce que je souhaiterai, c'est la combinaison des
deux : ^Z lance l'exécution de « print "signal receivedn"; » mais est
ignoré par le reste du programme.
--
Benoit Izac
Okay. C'est pas possible. SIGTSTP reste un signal. Et, sur ton systeme, ton
sleep est implemente en utilisant pause, qui va etre interrompu par les
signaux. Pour obtenir le resultat voulu, il faudra donc que tu remplaces
ton sleep par un truc plus complexe, qui note l'heure, qui fasse le sleep,
regarde comment celui-ci s'est fini, et en fasse un 2e si un TSTP est
passe par la... tu as peut-etre envie de regarder du cote de Time::HiRes
pour pouvoir faire des choses precises de ce cote-la.
Dans les cas pratiques que je connais, le fait qu'un signal interrompe
sleep n'est pas genant.
ton exemple jouet ne m'explique toujours pas pourquoi ca te gene pour
l'application que tu envisages. sans savoir ce que tu veux reellement faire,
c'est impossible de te conseiller une architecture plus adaptee...
Nota: tu as aussi une race condition dans ton exemple, mais peu visible vu
la brievete de tes process fils. Si tu tapes ^Z pile-poil au bon moment, tes
deux process vont le voir... et tu auras deux fois "signal received".
sleep renvoie tout ce qu'il faut pour pouvoir le relancer s'il est
interrompu.
-- Alain.
le 15/04/2010 à 09:34, Marc Espie a écrit dans le message
En fait, le fils récupère des données et remplit un fichier RRD et je
veux produire le graphique en envoyant un signal. Ce n'est effectivement
pas dramatique que la base soit mises à jour à deux secondes
d'intervalles au lieu de cinq.
Mon réel problème c'est (était) juste de comprendre pourquoi ça ne fait
pas ce que je souhaite.
Là, il me suffit d'ajouter « $SIG{TSTP} = 'IGNORE'; » dans le fils.
--
Benoit Izac