【问题标题】:How to count "reliably" 300 seconds time in perl?如何在 perl 中“可靠地”计算 300 秒时间?
【发布时间】:2014-05-16 12:55:57
【问题描述】:

如何设置 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 分钟”的正确方法是什么?

【问题讨论】:

  • 使用系统正常运行时间怎么样?有一个 Perl 模块会返回一个 int 值,表示正常运行时间(以秒为单位)。

标签: perl time


【解决方案1】:

我认为在这里使用警报功能是有意义的。

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

【讨论】:

  • 不错!警报()做得很好。它不受外部时钟变化的影响。谢谢。
【解决方案2】:

如果 try_something() 花费的时间可以忽略不计,您可以循环 100 次。或者如果系统很忙,以至于您的睡眠时间通常超过 3 秒,use Time::HiRes 'sleep'; 并将 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 ) );
}

【讨论】:

    【解决方案3】:

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

    select undef, undef, undef, 5*60;
    

    use IO::Poll;
    my $poll = IO::Poll->new;
    
    $poll->poll(5*60);
    

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 这不是真正的解决方案,因为 try_something() 大约需要 5 秒才能完成。
      • 然后将try_something换成一些时间检查,例如$t=time;$success=try_something();$t2=time-$t;if($t2&lt;100){$slept+=$t2}
      猜你喜欢
      • 2017-12-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-24
      • 2023-03-08
      • 1970-01-01
      • 2016-08-07
      • 2010-12-26
      相关资源
      最近更新 更多