1

「もの」を並行して処理する場合、フォーク/プロセスのすべてのニーズに次のテンプレートを使用しています。基本的に、一度に 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 ブロッキングの問題によるものだと思います) これを回避する唯一の方法は、親自身が子を kill -9 することだと私は考えています。

これを行うためにコードを変更する方法はありますか?

4

1 に答える 1

2

不安定になる可能性があるときはいつでも、それは貧乏人のアラームの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は子プロセスを起動します。2 つ目forkは、プロセスを実行して最初のプロセスを$time数秒後に強制終了するためのものです。

于 2013-04-05T19:57:00.743 に答える