2011-07-04 36 views
2

我想让子进程写入父类的@array。我读过有关管道,但我对如何真正实现它很困惑:如何使用Parallel :: ForkManager管道?

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; 

回答

9

如果你想使用管道,那么你需要你每次产卵前儿童打造一双管道,写来自孩子的书写管,并且使用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; 

这实际上工作。

+0

不错;完成的第二个参数是新的,而不是在我已经安装的旧版本中,但它很有意义,这个功能被合并到P :: FM本身中。 – ysth

+0

我完全反映了ysth的情绪。有人在我最近看到的部分代码中使用了第二个参数,但我并不知道P :: FM本身正在处理它。上次我看着P :: FM时,它不存在。谢谢! – ikegami

+0

真正有用的答案 - 谢谢。值得注意的是,run_on_finish中sub的第5个参数总是包含数据结构。我的($ pid,$ exit_code,$ ident,$ exit_signal,$ core_dump,$ data_structure_reference)= @_; – hardingnj

相关问题