Perl中$SIG{ALRM}的超时处理

发布时间:2020-09-13编辑:脚本学堂
Perl中$SIG{ALRM}的超时处理,感兴趣的朋友可参考下。在perl中运行一些独立的程序时可能会挂起会处理较长时间,这种情况下可以使用alarm。

Perl中$SIG{ALRM}的超时处理,感兴趣的朋友可参考下。

SIGALRM
Sent when the timer set by the alarm function expires (《perl cookbook》)
http://perldoc.perl.org/functions/alarm.html

在perl中运行一些独立的程序时可能会挂起会处理较长时间,这种情况下可以使用alarm。
#!/usr/bin/perl -W
$timeout=5;
eval {
        local $SIG{ALRM} = sub { die "$timeout second,run alarmn" };#定义alarm运行的程序,这里设定为die并打印信息。
        alarm $timeout; #设定 5秒后进入超时处理
        sleep 20; 
        print "in alarm evaln";#因为5秒后会进入超时处理,die会中断eval块,所以这里并不会运行。
alarm (0); #所需的程序已经运行完成,取消超时处理
};
print "out of alarm evaln" 
#####后续处理
if ($@) {
    if ($@ =~ /die in sig alarm/) {
      print "caught the error";
    }
    else {
      print $@;
    }
  }
}

经过timeout时间,会进入超时处理,在上面的例子中,die会中断eval块的处理,但是不会结束整个程序,eval块以后的程序仍会运行,这就是为什么要使用eval的原因。
如果将sleep改为2,小于timeout时间,则不会进入超时处理,则eval块内的print也会运行。

同一时间只能有一个超时时间,每次调用alarm,取消前面的一个超时时间。alarm 0用于取消前一个超时时间,但不启动一个新的超时时间。

再一个例子,这里没有使用eval
$SIG{ALRM} = sub {
        system("killall -9 firefox") or warn "Fail to kill firefox process n";
        print join '', time2str("[%Y-%m-%d %H:%M:%S] ", time), "Wait too long, kill the firefox process n";
};

alarm 120; #120s后kill掉firefox进程。
system(“firefox”);
alarm 0; #取消超时处理