GNT sans publicité, site mobile, fonctionnalitées exclusives...

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
Lire les 15 réponses

Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 3
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
espie
Le #21558311
In article 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 ?



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.
Benoit Izac
Le #21558431
Bonjour,

le 15/04/2010 à 00:38, Marc Espie a écrit dans le message

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.



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
espie
Le #21559571
In article Benoit Izac
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.



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".
Alain Ketterlin
Le #21559701
(Marc Espie) writes:

In article Benoit Izac
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.



Okay. C'est pas possible. SIGTSTP reste un signal. Et, sur ton systeme, t on
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...



sleep renvoie tout ce qu'il faut pour pouvoir le relancer s'il est
interrompu.

-- Alain.
Benoit Izac
Le #21559871
Bonjour,

le 15/04/2010 à 09:34, Marc Espie a écrit dans le message

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.



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...



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.

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".



Là, il me suffit d'ajouter « $SIG{TSTP} = 'IGNORE'; » dans le fils.

--
Benoit Izac
Publicité
Suivre les réponses
Poster une réponse
Anonyme