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;
}
另外一个澄清的问题。僵尸总是不好对吧?
起初,我的印象是,僵尸进程只是他们父母尚未恢复的进程。现在我想知道我的代码是不是在等待孩子们。
你不觉得Parallel :: ForkManager已经使用了SIGCHLD处理程序吗? – mob
太棒了,我担心有一个代码味道:僵尸。也许我错过了关于共享状态的细节。正如你所说的,可能是孩子们在wait_all_children到达之前完成的。关于on_finish有趣的一点,当我看到自己使用更多的ForkManager时,我会记住这一点。 – cwisch
@mob,它不会(除非在非常特定的情况下,在非常局部的区域)。如果是这样,僵尸会在我加入的线路出现后立即收获。 – ikegami