Как мне конвейер с использованием Parallel :: ForkManager? - PullRequest
2 голосов
/ 04 июля 2011

Я хочу, чтобы дочерние процессы записывали в родительский @array. Я читал о трубопроводе, но я очень смущен тем, как на самом деле это реализовать:

use Parallel::ForkManager;
my @array;
my $pm=new Parallel::ForkManager(3); 

    for((1..5)){
    $pm->start and next; 
    print "child: ".$_."\n";
    push(@array,$_); # what do I do here to put it into the parent's @array????
    $pm->finish; 
    }
$pm->wait_all_children;


print "parent: ".$_."\n" for @array;

1 Ответ

9 голосов
/ 04 июля 2011

Если вы хотите использовать каналы, то вам нужно создать пару каналов, прежде чем вы породите каждого потомка, записать в канал записи из дочернего элемента и использовать IO :: Select для чтения из всех чтения заканчивается параллельно в родительском. Вам также нужно будет изменить способ ожидания детей, поскольку ForkManager wait_all_children блокирует, что не очень полезно. Вы можете использовать метод run_on_start для регистрации каждого процесса в хэше и метод run_on_finish для удаления каждого процесса после его смерти, а затем завершить цикл выбора, когда не осталось ни одного процесса.

Или, если не важно, что дети могут передавать свои результаты родителю в режиме реального времени, вы можете использовать способность ForkManager передавать данные обратно родителю при выходе через вызов finish, который будет выглядеть примерно так:

#!perl
use strict;
use warnings;
use Parallel::ForkManager;

# No indirect object notation
my $pm = Parallel::ForkManager->new(3);
my @array;
$pm->run_on_finish(sub {
    my $return = $_[5]; # Count 'em.
    push @array, @$return;
});

for(1..5) {
  $pm->start and next;
  print "child: $_\n";
  $pm->finish(0, [$_]);
}

$pm->wait_all_children;

print "parent: $_\n" for @array;

что на самом деле работает.

...