Ways to do timeouts in Perl?

前端 未结 3 708
滥情空心
滥情空心 2020-12-03 05:14

I frequently use the following pattern to set an upper bound to the running time of a particular code fragment in Perl:

my $TIMEOUT_IN_SECONDS = 5;
eval {
           


        
3条回答
  •  轻奢々
    轻奢々 (楼主)
    2020-12-03 05:42

    Take care with signal handling. Perl receives signals asynchronously and they may be lost or interfere with each other if a signal is received while another signal is being handled by the callback.

    Event-handling libraries' Win32 support is pretty so-so in Perl (I have to support non-cygwin Win32), so I generally use a simple polling loop for timeouts:

    use Time::HiRes qw(sleep);
    
    sub timeout {
      my $timeout = shift;
      my $poll_interval = shift;
      my $test_condition = shift;
      until ($test_condition->() || $timeout <= 0) {
        $timeout -= $poll_interval;
        sleep $poll_interval;
      }
      return $timeout > 0; # condition was met before timeout
    }
    
    my $success = timeout(30, 0.1, \&some_condition_is_met);
    

    The sleep timer can be easily made user- or caller-configurable and unless you are doing an extremely tight loop or have multiple callers waiting on the loop (where you can end up with a race or dead lock), it is a simple, reliable, and cross-platform way to implement a timeout.

    Also note that the loop overhead will mean that you cannot guarantee that the timeout is observed absolutely. $test_condition, the decrement, garbage collection, etc. can interfere.

提交回复
热议问题