2016-08-05 34 views
2

Ein Stück Code, den ich schreibe, verwendet Parallel::ForkManager und ich merke, dass es viele Zombies erstellt, während das Skript läuft. Ich frage mich, ob mir etwas fehlt, wenn es um die wait_all_children geht.Warum erstellt mein Code mit Parallel :: ForkManager Zombies?

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; 
} 

Auch eine klärende Frage. Zombies sind immer schlecht, oder?

Zuerst hatte ich den Eindruck, dass Zombie-Prozesse nur Prozesse sind, die noch nicht von ihren Eltern wiederhergestellt wurden. Jetzt frage ich mich, ob mein Code überhaupt auf die Kinder wartet.

Antwort

4

P :: FM wird nur erfasst, wenn start aufgerufen wird und die maximale Anzahl der untergeordneten Elemente ausgeführt wird, und wenn wait_children oder wait_all_children aufgerufen werden. Kinder, die austreten, werden bis dahin zu Zombies.

Sie werden nie mehr Kinder haben (einschließlich Zombies) als angegeben, so dass die vorübergehende Anwesenheit von Zombies ist keine schlechte Sache [1]. Der einzige Haken ist, dass der run_on_finish -Handler nur ausgeführt wird, wenn der untergeordnete Prozess abgearbeitet wird. Dies bedeutet, dass er nicht so schnell wie möglich aufgerufen wird.

Ich glaube, Sie folgende verwenden können, früher Kinder zu ernten:

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

  1. Siehe Is a persistent zombie process sign of a bug? für eine allgemeine Antwort.
+0

Sie denken nicht, dass Parallel :: ForkManager bereits den SIGCHLD-Handler verwendet? – mob

+0

Großartig, ich war besorgt es gab einen Code Geruch re: Zombies. Vielleicht hatte ich ein Detail über den geteilten Staat verpasst. Wie du schon sagtest, könnte es sein, dass die Kinder fertig sind, bevor die wait_all_children erreicht sind. Interessantes über das on_finish, das werde ich im Hinterkopf behalten, da ich mehr ForkManager benutze. – cwisch

+0

@mob, tut es nicht (außer unter sehr spezifischen Umständen in einem sehr lokalisierten Bereich). Wenn dies der Fall wäre, würden die Zombies sofort nach dem Child-Exit ernten, wenn die von mir hinzugefügte Zeile dies tut. – ikegami