如何在perl中“可靠地”计算300秒的时间?

时间:2014-05-16 12:55:57

标签: perl time

如何暂停5分钟?

我的程序正在执行此操作:

# 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);
}

问题:该程序在启动后运行。它运行的嵌入式系统没有rtc / clock电池。时钟从2000年1月1日开始,然后在它运行的第一分钟,它获得网络并且ntp将时钟设置为更新的时钟,使循环在5分钟超时之前退出。

哪个是在perl脚本中“计算5分钟”的正确方法,即使系统时钟被其他外部程序更改了?

4 个答案:

答案 0 :(得分:4)

我认为使用闹钟功能会有意义。

{
  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);
}

答案 1 :(得分:1)

如果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 ) );
}

答案 2 :(得分:0)

你想使用其中一个单调计时器;例如selectpoll超时使用它。

select undef, undef, undef, 5*60;

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

$poll->poll(5*60);

答案 3 :(得分:0)

sleep的返回值是睡眠的实际秒数。您可以检查此值并忽略任何异常大的值:

$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
      }
   }
}