如何管道使用Parallel :: ForkManager?

时间:2011-07-04 18:01:14

标签: perl fork pipe

我想让子进程写入父进程的@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 个答案:

答案 0 :(得分:9)

如果你想使用管道,那么你需要在产生每个孩子之前创建一对管道,从孩子写入书写管道,并使用IO::Select从所有读取结束读取在父母中并行。你还需要改变你等待孩子的方式,因为ForkManager的wait_all_children是阻塞的,这不是很有用。您可以使用run_on_start方法在散列中注册每个进程,并使用run_on_finish方法在每个进程终止后删除它们,然后在没有剩余进程时终止select循环。

或者,如果孩子们可以将他们的结果实时传递回父母并不重要,那么你可以使用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;

实际上有效。