At 11:46 AM -0700 2002-05-29, Jay Soffian wrote:
> "IK" == Ilmari Karonen <[EMAIL PROTECTED]> writes:
>
>IK> Isn't this rather needlessly complex?
>
>Nope, not needlessly.
>
>IK> Essentially the same results can be achieved by simply counting
>IK> the (possibly inaccurate) time taken by sleep() as part of the
>IK> next iteration. Like this:
>
> use Time::HiRes qw(time sleep); # optional, for subsecond precision
> my $step = 0.1; # ten iterations per second
>
> my $t = time;
> while (1) {
> # do stuff...
> } continue {
> $t += $step; # watch out for rounding errors!
> my $delay = time - $t;
> sleep $delay if $delay > 0;
> }
>
>I think you meant $t - time;
No, I'm fairly sure it works best the way Ilmari wrote it...
>IK> This is guaranteed to maintain the correct average rate regardless
>IK> of any variations in the execution time of the loop, and will
>IK> automatically compensate for any systematic errors in sleep().
>IK> Non-systematic errors, of course, are unavoidable, but are
>IK> guaranteed not to propagate.
>
>Ah, but I don't want to maintain the average rate in all cases. This
>code was written to limit packets being sent out over the network. If
>the packet sending code falls behind significantly for some reason
>(say because someone paused the process), I don't want the code to run
>through the loop as quickly as possible till it brings the average
>rate back up. Rather, the code gives up if it has fallen too far
>behind and resets the rate (I'll make how far behind it can fall
>configurable).
>
How about:
use Time::HiRes qw(time sleep); # optional, for subsecond precision
my $step = 0.1; # ten iterations per second
my $max_delay = 5.0; # trigger for reset
my $t = time;
while (1) {
# do stuff...
} continue {
$t += $step; # watch out for rounding errors!
my $delay = time - $t;
$delay > $max_delay and &reset; # exit loop to reset
$delay > 0 and sleep $delay
}
--
- Bruce
__bruce_van_allen__santa_cruz_ca__