How can I tell Perl to run some code every 20 seconds?
See Schedule::ByClock:
#!/usr/bin/perl
use strict; use warnings;
use Schedule::ByClock;
my $scheduler = Schedule::ByClock->new(0, 20, 40);
while ( defined( my $r = $scheduler->get_control_on_second ) ) {
printf "%02d\n", $r;
}
All the caveats others pointed out still apply, but I think the module is neat.
While the sleep
function will work for some uses, if you're trying to do "every 20 seconds, forever", then you're better off using an external utility like cron
.
In addition to the possible issue of drift already mentioned, if your sleep
script exits (expectedly or otherwise), then it's not going to run again at the next 20 second mark.
@Blrfl is correct, and I feel sheepish. That said, it's easy enough to overcome.
* * * * * /path/to/script.pl
* * * * * sleep 20 && /path/to/script.pl
* * * * * sleep 40 && /path/to/script.pl
You could also take a hybrid approach of putting a limited count sleep loop in the script and using cron to run it every X minutes, covering the case of script death. Anything more frequent than 20 seconds, I would definitely take that approach.
while (1) {
sleep 20;
<your code here>;
}
#!/usr/bin/perl -w
use strict;
# heartbeat
$SIG{ALRM} = sub {
# set up the next signal for 20 second from now
alarm(20);
printf "<heartbeat/>\n";
};
alarm(20); # start timer
my $i = 0;
while(1) {
$i++;
printf "loop" . $i . "\n";
sleep 2;
}
alarm(0);
printf "done!\n";
Output :
loop1
loop2
loop3
loop4
loop5
loop6
loop7
loop8
loop9
loop10
<heartbeat/>
loop11
loop12
loop13
loop14
loop15
loop16
loop17
loop18
loop19
loop20
<heartbeat/>
for (;;) {
my $start = time;
# your code;
if ((my $remaining = 20 - (time - $start)) > 0) {
sleep $remaining;
}
}
Go with ..
while () {
sleep 20;
#Code here
}