Allthough the concept of the practicality is correct, i think the practicality hasn't changed (at least not until copy-on-write, as far as i know), nor has the concept - it's still liable to fluxuate on a very long term basis... But at least this can be treated more of a O(1) than O(N) operation. Sadly my needs are probably O(1) to start with... This should help with blocking tho, which is a plus.
If the action is costly enough i reckon i'd wrap it in a thread, but that's probably only if the task might actually take longer than the sleep interval... i dunno.
I haven't thought of the constant time before, although it's a possibility. It's fragile points are a busy time sharing system (where the spawning time may vary wildly), and calculation. An alternative is to start with zero as a the deduced value, and then to loop some like in my code above. We cache the startup time aswell, and know (via multiplication) the time we spent sleeping. We can then calculate how much time was not slept, based on the real time which has passed, and that value, divided by the number of times we have performed the action since our 'startup' can be taken off the sleep intervals. If it's too much the value can ofcourse become negative, and thus add to the accuracy. If the action is short enough we can just omit the thread spawning part.
Thanks dearly for that constant concept, it really made me think... =)
I wish there was an 'alarm_every' system call ;-)
Update: i have written some Time::HiRes dependant code, which doesn't use signals. It swings around the desired frequency with an accuracy of around 1 millisecond on my machine, correcting itself as needed. Here is the source code:
#!/usr/bin/perl
use strict;
use warnings;
use Time::HiRes qw(usleep gettimeofday);
my $microseconds = 1_000_000;
my $iter = 10;
my $tflux = 0;
my $flux = 0;
my $titer = $iter;
my $sleep = $microseconds;
my $count = 0;
my ($start_s, $start_m) = gettimeofday;
my ($is, $im) = ($start_s, $start_m);
my ($seconds, $micro) = ($start_s, $start_m);
my $diff = 0;
foo: {
# tflux serves as gravity
# flux serves as inertia
$diff = int ( ($flux + $tflux) / 2 + 0.5);
$sleep -= $diff;
print "sleeping for $sleep\nelapsed time: " . (($start_s - $is) *
+1_000_000 + $start_m - $im) . "\ntotal correction: $tflux\ncorrected
+from last: $flux\naverage: $diff\n";
for (1 .. $iter){
action();
usleep $sleep;
}
($seconds, $micro) = gettimeofday();
$flux = # difference from the last iteration
( (($seconds - $start_s) * 1_000_000) # elapsed seconds
+
$micro - $start_m # elapsed micro seconds
-
$microseconds * $iter # desired interval of entire loo
+p
) / $iter;
$tflux = # difference from desired total time
(
(($seconds - $is) * 1_000_000) # elapsed seconds
+
$micro - $im # elapsed micro seconds
-
$microseconds * $titer # desired interval of entire lo
+op
) / $titer;
$titer += $iter;
($start_s, $start_m) = gettimeofday();
redo foo;
}
sub action {
$count++;
usleep 100;
}
1; # keep your mother happy
__END__
-nuffin
zz zZ Z Z #!perl