我写的一段代码使用Parallel::ForkManager,我注意到它在脚本运行时会创建许多僵尸。我想知道在wait_all_children
时我是否遗漏了一些东西。
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;
}
也是一个澄清问题。僵尸总是坏的吗?
起初我的印象是,僵尸流程只是尚未被其父母恢复的流程。现在,我想知道我的代码是不是在等待孩子们。
答案 0 :(得分:4)
P :: FM仅在调用start
并且最大子项数正在运行且调用wait_children
或wait_all_children
时收到。在那之前退出的孩子们变成了僵尸。
你永远不会有比指定更多的孩子(包括僵尸),所以僵尸的临时存在并不是一件好事 [1] 。唯一的问题是run_on_finish
处理程序只会在收到子进程时执行,因此这表示它没有被尽快调用。
我相信您可以使用以下方法更快地收获孩子:
$SIG{CHLD} = sub { $pm->wait_children };