2D数组和Parallel :: ForkManager,数组在分叉后然后分配值是空的?

时间:2013-06-06 22:34:59

标签: arrays perl

我使用forkmanager同时运行任务而不是顺序运行任务。我已将实际代码转换为以下代表代码逻辑的示例代码。

#!/usr/bin/perl -w 
use strict;
use Data::Dumper;
use Parallel::ForkManager;

my @array2d = () ;



my $dim1Items = 4;
my $dim2Items = 3;

my $dim1Manager = Parallel::ForkManager->new($dim1Items);
for (my $i = 0; $i <= $dim1Items ; $i++) {
        $dim1Manager->start and next;


        my $dim2Manager = Parallel::ForkManager->new($dim2Items);
        for (my $j = 0; $j <= $dim2Items; $j++) {
                $dim2Manager->start and next;

                $array2d[$i][$j] = "$i\t$j" ;

                $dim2Manager->finish;
        }
        $dim2Manager->wait_all_children;


        $dim1Manager->finish;
}
$dim1Manager->wait_all_children;

print Dumper(@array2D) ; 

然后我运行Dumper(@ 2dArray)来查看内容,但是我得到了空字符串,这意味着数组是空的。我尝试了我的值赋值语法而没有分叉,它起作用 - 所以我必须在分叉时做错事。

2 个答案:

答案 0 :(得分:6)

分叉是创建一个新进程,它是当前进程的副本。在一个进程中更改变量不会在其他进程中更改类似命名的变量。

P :: FM确实提供了一种将数据传递回父进程的机制。它是documented标题下的“从子进程中检索DATASTRUCTURES”。

use Data::Dumper          qw( Dumper );
use Parallel::ForkManager qw( );

use constant MAX_WORKERS => 10;
use constant { DIM1_ITEMS => 4, DIM2_ITEMS => 3 };

my @aoa;

my $pm = Parallel::ForkManager->new(MAX_WORKERS);
$pm->run_on_finish(sub {
   my ($pid, $exit_code, $ident, $exit_signal, $core_dump, $result_ref) = @_;
   my ($i, $j) = @$ident;

   warn("Child $i,$j killed by signal $exit_signal"), return if $exit_signal;
   warn("Child $i,$j exited with error $exit_code"),  return if $exit_code;
   warn("Child $i,$j encountered an unknown error"),  return if !$result_ref;

   $aoa[$i][$j] = $$result_ref;
});

for my $i (0..DIM1_ITEMS-1) {
   for my $j (0..DIM2_ITEMS-1) {
      $pm->start([ $i, $j ]) and next;

      my $result = "$i\t$j";

      $pm->finish(0, \$result);
   }
}

$pm->wait_all_children();

print(Dumper(\@aoa));

(你有两个级别的P :: FM是没有意义的。你应该有一个F :: PM,其最大子女数量取决于你拥有的核心数量和一些实验。)

答案 1 :(得分:1)

正如ikegami所说,子进程在自己的内存空间中运行,并且它对变量的更改不会传播回父进程,除非您进行某种形式的进程间通信。 Forks::Super模块使这种事情变得非常容易。

use Forks::Super;

my @array2d;
for my $i (0 .. 3) {
  for my $j (0 .. 2) {
    fork {
      share => [ \$array2d[$i][$j] ],
      sub => sub {
        sleep 1 + rand 4;
        $array2d[$i][$j] = "$i\t$j";
      },
    };
  }
}
waitall;
print Dumper(\@array2d);