如何在我的perl脚本中删除花费太长时间的分叉进程,而不会超时分叉进程?

时间:2013-04-05 19:29:43

标签: perl fork kill

在处理“事物”并行时,我一直在使用以下模板来满足我的所有分叉/处理需求。它基本上遍历我需要处理的所有内容,一次X个条目,以及任何花费太长时间的条目的时间:

my $num_procs = 0;
foreach my $entry (@entries) {
  $num_procs++;
  if($num_procs == $MAX_PROCS) {
    wait();
    $num_procs--;
  }
  my $pid = fork();
  if($pid == 0) {
    process($entry);
  } 
}
for (; $num_procs>0; $num_procs--) {
  wait();
}

“process”例程具有以下模板,该过程超时:

my $TIMEOUT_IN_SECONDS = 15;
eval {
  local $SIG{ALRM} = sub { die "alarm" };
  alarm($TIMEOUT_IN_SECONDS);       

  # do something

  alarm(0);
};
if ($@) {
  # do something about the timeout
}   

我现在遇到一个问题,这个问题不再有效,因为孩子无法自拔。 (我认为这是由于NFS的I / O阻塞问题)我想,解决这个问题的唯一方法是让父母本身杀死孩子。

有没有办法修改我的代码来执行此操作?

1 个答案:

答案 0 :(得分:2)

每当alarm出现问题时,the poor man's alarm就是一个很好的用例:

my $pid = fork();
if ($pid == 0) {
    ...  # child code
    exit;
}
if (fork() == 0) {
    my $time = 15;
    exec($^X, "-e", "sleep 1,kill(0,$pid)||exit for 1..$time;kill -9,$pid");
    die; # shouldn't get here 
}

第一个fork会触发您的子进程。第二个fork用于运行进程以在$time秒后终止第一个进程。