【问题标题】:How can I kill forked processes that take too long in my perl script without timing out the forked process?如何在不超时分叉进程的情况下杀死在我的 perl 脚本中花费太长时间的分叉进程?
【发布时间】:2013-04-05 19:29:42
【问题描述】:

在并行处理“事物”时,我一直在使用以下模板来满足我的所有分叉/流程需求。它基本上循环遍历我需要处理的所有内容,一次 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();
}

“进程”例程具有以下模板,该模板使进程超时:

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 阻塞问题)我认为解决这个问题的唯一方法是让父母自己杀死 -9 孩子。

有没有办法修改我的代码来做到这一点?

【问题讨论】:

标签: perl fork kill


【解决方案1】:

只要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 秒后杀死第一个进程。

【讨论】:

    猜你喜欢
    • 2012-04-22
    • 1970-01-01
    • 2016-06-30
    • 1970-01-01
    • 2010-11-12
    • 2017-12-28
    • 2019-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多