edan has asked for the wisdom of the Perl Monks concerning the following question:
I have a daemon that runs in a loop which is driven by a poll on several sockets, and a bunch of timers that go off on various intervals. I have implemented a simple timer mechanism by keeping a hash of timers, where each timer is represented by a code-ref for the function that should be called when the timer goes off, and the next time when the counter should go off. This is calculated by adding the timer's interval to the current time as returned by time(). This works great, except when someone changes the system clock... then all my timers are hopelessly out of whack!
So, I want to keep my current code as unchanged as possible, but insulate myself from system-clock changes. What suggestions do my fellow monks have for getting a tick every second without calling time()? I banged out the following code as a first shot:
my $counter; init_timer(); while(1) { select(undef, undef, undef, 0.5); print "$counter " . scalar(localtime) . "\n"; } sub init_timer { $counter = 0; $SIG{ALRM} = \&tick; alarm(1); } sub tick { alarm(1); $counter++; }
This seems to work, but I don't know if it is a good/safe way to do it... is it okay to set a new alarm from within the SIGALRM signal handler? Are there any other gotchas (besides not being able to intermix any sleep() calls in my program, which I don't do anyway)? Will it pretty reliably give me a tick every second (I don't need anything terribly HiRes at this point... if I ever do, I suppose it wouldn't be too hard to retrofit it with Time::HiRes...)
TIA
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: system-clock-safe timers without time()?
by tachyon (Chancellor) on Apr 13, 2003 at 13:12 UTC | |
by hatter (Pilgrim) on Apr 13, 2003 at 17:21 UTC | |
|
Re: system-clock-safe timers without time()?
by rob_au (Abbot) on Apr 14, 2003 at 02:45 UTC | |
|
Re: system-clock-safe timers without time()?
by fizbin (Chaplain) on Apr 14, 2003 at 14:11 UTC | |
by edan (Curate) on Apr 15, 2003 at 11:10 UTC |