How to count "reliably" 300 seconds of time in perl?

How can I time out 5 minutes?

My program does this:

# I need to try something every 3 seconds, for at most 5 minutes
$maxtime = time() + (5 * 60);
$success = 0;
while (($success == 0) && (time() < $maxtime)) {
  $success = try_something();
  sleep (3) if ($success == 0);
}

Problem: This program starts immediately after loading. The built-in system in which it works does not have an rtc / clock battery. The clock starts in January / 1/2000, then in the first minute it starts, it receives a network, and ntp sets the clock to the updated clock, making the loop exit before the timeout of 5 minutes.

What is the correct way to "count 5 minutes" inside a perl script, even if the system clock is changed by another external program?

+4
source share
4 answers

I think using the alarm function makes sense here.

{
  local $SIG{ALRM} = sub {
     warn "Ooops! timed out, exiting";
     exit(100); # give whatever exit code you want
  };

  ## setup alaram
  alarm( 5 * 60 );
  my $success = 0;
  until($success) {
    $success = try_something()
       or sleep 3;
  }

  ## deactivate alarm if successful
  alarm(0);
}
+4
source

try_something() , 100 . , , 3 , use Time::HiRes 'sleep'; , 300.

, - :

my $last_time = my $start_time = time();
while () {
    try_something() and last;
    my $time = time();
    # system clock reset? (test some limit that is more than try_something could ever take)
    if ( $time - $last_time > 86400 ) {
        $start_time += $time - $last_time;
    }
    $last_time = $time;
    sleep( List::Util::min( 3, $start_time + 300 - $time ) );
}
+1

You want to use one of the monotonous timers; for example, timeout selectand polluse this.

select undef, undef, undef, 5*60;

or

use IO::Poll;
my $poll = IO::Poll->new;

$poll->poll(5*60);
0
source

The return value sleepis the actual number of seconds. You can check this value and ignore any values ​​that were unusually large:

$success = 0;
$slept = 0;
while (($success == 0) && ($slept < 300)) {
  $success = try_something();
  if ($success == 0) {
      $n = sleep 3;
      if ($n <= 3) {
          $slept += $n;
      } else {
          # looks like the clock just got updated
      }
   }
}
0
source

Source: https://habr.com/ru/post/1540838/


All Articles