2016-08-05 3 views
2

私が書いているコードにはParallel::ForkManagerが使われていて、スクリプトが実行されるときに多くのゾンビが作成されていることに気付いています。私はそれがwait_all_childrenに来るときに何かを逃しているのだろうかと思います。なぜ私のコードはParallel :: ForkManagerを使ってゾンビを生成していますか?

my $fork_manager = new Parallel::ForkManager->($ENV{CPUS}) 

for(my $i = 0; $i < scalar @plates; $i++){ 
    my $offset = get_full_plate_offsets(@{$plates[$i]}); 
    make_path(File::Spec->catfile($tmp_dir, $i)); 
    foreach my $cell (keys %{$offset}){ 
     my($x, $y) = @{$offset->{$cell}}; 
     $fork_manager->start("$cell @ $x, $y") and next; 
     my $out_file = File::Spec->catfile($tmp_dir, $i, "$cell.jpg"); 
     my $out_text = File::Spec->catfile($tmp_dir, $i, "$cell.txt"); 
     split_file($input_jpg, [$x, $y], $out_file); 
     my $result = do_something($out_file); 
     open(my $FH, '>', $out_text); 
     print $FH "$result\n"; 
     $fork_manager->finish; 
    } 
    $fork_manager->wait_all_children; 
} 

また明確な質問です。ゾンビはいつも悪いですか?

最初は、ゾンビプロセスは、まだ自分の親によって回復されていないプロセスであるという印象を受けました。私のコードが子供たちをまったく待っているのではないかと思っています。

答えて

4

startが呼び出され、子の最大数が実行されているとき、およびwait_childrenまたはwait_all_childrenが呼び出されたときに、P :: FMがリープします。それまでに終了した子供たちはゾンビになります。

ゾンビの一時的な存在は悪いことではありませんので、指定された以上の子供(ゾンビを含む)を持つことはありません[1]。唯一のキャッチは、run_on_finishハンドラは、子プロセスが収穫されたときにのみ実行されるため、できるだけ早く呼び出されていないことを示しています。一般的な答えを参照Is a persistent zombie process sign of a bug?

$SIG{CHLD} = sub { $pm->wait_children }; 

  1. 私はあなたが早く子供を享受するために、以下を使用することができると信じています。

+0

Parallel :: ForkManagerはすでにSIGCHLDハンドラを使用しているとは思われませんか? – mob

+0

偉大な、私はコードのにおいがあったことを心配していた:ゾンビ。おそらく私は共有状態についての詳細を見逃していたでしょう。あなたが言ったように、wait_all_childrenに達する前に子どもたちが完了している可能性があります。 on_finishについての面白いことに、私はForkManagerの多くを使って自分自身を見ていることを念頭に置いておきます。 – cwisch

+0

@mob、そうではありません(非常に限定された地域の非常に特殊な状況を除いて)。そうした場合、ゾンビは私が追加した行のように子どもの退室直後に収穫されます。 – ikegami

関連する問題