2015-12-02 51 views
1

我试图在报警触发时重试某些逻辑。那可能吗。 我已经定义报警如下:Perl在报警时重试

local $SIG{ALRM} = sub { 
     if($attempt <=5) { 
       print "NExt attempt\n"; 
       $attempt = $attempt + 1; 
       my $val = subroutine_call(); 
     } else{ 
     Carp::confess "Die now\n"; 
     } 

我的代码片段如下:

foreach my $x (@array) 
{ 
    eval { 
     alarm(2); 
     my $val = subroutine_call(); 
     alarm(0); 
    }; 

    print "Moving on \n"; 
    ## some code 
    } 

我想要重试调用subroutine_call高达3次报警时终止应用程序之前触发。调用subrountine_call(不管是否在警报触发后调用它),它应该显示打印语句。

我知道,一旦警报被触发,并且通过警报定义触发了subrountine_call,代码流就会偏离,并且它不会执行打印语句。如果报警不会触发,我希望它表现得好像它会有的一样。

这可能吗?我很怀疑,但想知道是否是这样。

感谢,

回答

5
local $SIG{ALRM} = sub { die "alarm\n"; }; 

for my $x (@array) { 
    my $attempts_remaining = 3; 
    while (1) { 
     last if eval { 
     alarm(2); 
     subroutine_call(); 
     alarm(0); 
     return 1; 
     }; 

     my $e = [email protected]; 
     die($e) if $e ne "alarm\n"; 
     die("Timeout!\n") if !--$attempts_remaining; 
     warn("Timeout! Trying again...\n"); 
    } 
} 
+0

感谢。这工作。但是这个问题。在应用程序死亡3次后,显示的错误信息是“超时”,这是公平的。什么是重要的本地$ SIG {ALRM} =子{死“报警\ n”; };声明涉及此?终止时不打印“警报”。我相信它应该打印$ SIG {ALRM}中提到的消息,而不是在尝试耗尽时显式死亡。 – learningMyWayThru

+0

恩,如果你不喜欢这个消息,或者想要做一些除了死亡之外的事情,没有什么能阻止你。 //区分超时和其他例外。 – ikegami