J'ai ce simple démon perl:Est-ce que le sommeil est interrompu quand un signal est reçu en perl?
#!/usr/bin/perl
use strict;
use warnings;
use Proc::Daemon;
Proc::Daemon::Init;
my $continue = 1;
$SIG{TERM} = sub { $continue = 0 };
$SIG{USR1} = sub { do_process(1) };
# basic daemon
boxesd_log("started boxesd");
while ($continue) {
do_process(0);
sleep(30);
}
boxesd_log("finished boxesd");
exit(0);
# required subroutines
sub do_process {
my ($notified) = @_;
boxesd_log("doing it $notified");
}
Mais il y a quelque chose qui ne fonctionne pas correctement.
Lorsque le démon démarre, il enregistre toutes les 30 secondes sans notification comme prévu:
Sat Oct 30 21:05:47 2010 doing it 0 Sat Oct 30 21:06:17 2010 doing it 0 Sat Oct 30 21:06:47 2010 doing it 0
Le problème vient quand j'envoie le signal USR1
au processus en utilisant kill -USR1 xxxxx
. La sortie est pas ce que je pense:
Sat Oct 30 21:08:25 2010 doing it 1 Sat Oct 30 21:08:25 2010 doing it 0
je reçois deux entrées consécutives, l'une de la sous-routine de traitement du signal et une autre forme la boucle toujours en cours d'exécution. Il semble que le sommeil soit interrompu à chaque fois que le signal USR1
est reçu.
Que se passe-t-il?
Vous n'êtes pas en train de vérifier si votre deuxième 'sleep' a été interrompu aussi. Pour le gérer correctement, vous avez besoin d'une boucle de quelque sorte, pas seulement un 'if'. – cjm
Er, la réponse éditée est une boucle infinie. :( – mark4o
@ mark4o: infini jusqu'à ce qu'un signal l'interrompt, oui, ce qui est généralement ce que font les démons. (J'ai enlevé la variable '$ continue' pour plus de clarté, car elle ne correspondait pas à la question centrale de comment' sleep' se comporte Il est évident que l'on pourrait vouloir rendre le code plus compliqué, par exemple dormir à nouveau sur une seconde interruption comme cjm mentionné.) – Ether