user3158991
user3158991

Reputation: 21

How can I stop a Perl subroutine if it takes too long?

I created a subroutine sub_info in Perl. So in my Perl script, it reads each line of input file and call sub_info subroutine. However, for some of the input lines, sub_info takes very long time to run. So basically I want to calculate the running time of sub_info subroutine for each of input line and if it takes more than 15 minutes, I want to pass that input line and run sub_info subroutine for next input line. Is there any function to calculate time for running a subroutine in Perl?

Upvotes: 2

Views: 685

Answers (1)

René Nyffenegger
René Nyffenegger

Reputation: 40499

I'd probably go with some combination of SIG{ALRM} and alarm:

use warnings;
use strict;

$|=1;

for my $i (1 .. 10) {

  local $SIG{ALRM} = sub {
    die;
  };

  eval {
    alarm 5;
    sub_info($i);
  };

  if ($@) {
    print "aborted\n";
  }
  alarm 0;
}

sub sub_info {
  my $i = shift;
  my $r = int(10*rand);

  printf "Trying %2d for %2d seconds: ", $i, $r;
  sleep $r;
  print "finished\n";
}

With alarm n you specify that after n seconds a SIGALRM signal is delivered to the calling process. When the processes receives such a signal, it does what is specified in $SIG{ALRM}. In the sample script above it just dies.

So, if a sub_info call takes less than 5 seconds, die is not invoked, yet if it takes more, the die is invoked.

You don't want the entire process to die, so you wrap the call to sub_info into an eval block. If the eval block has died, $@ will be set. So you check for a true value in $@ in which case you know that 5 seconds were exceeded.

Upvotes: 2

Related Questions