1

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) を実行して内容を確認しましたが、配列が空であることを意味する null 文字列が返されました。フォークせずに値の割り当て構文を試してみましたが、うまくいきました。つまり、フォークで何か間違ったことをしているに違いありません。

4

2 に答える 2

6

フォークとは、現在のプロセスのコピーである新しいプロセスを作成することです。あるプロセスで変数を変更しても、他のプロセスの同様の名前の変数は変更されません。

P::FM は、データを親プロセスに戻すメカニズムを提供します。「子プロセスからのデータ構造の取得」という見出しの下に文書化されています。

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 の 2 つのレベルを持つことは意味がありませんでした。あなたが持っているコアの数といくつかの実験に基づく子の最大数を持つ 1 つの F::PM を持つべきです。)

于 2013-06-06T22:39:46.753 に答える
1

池上が言うように、子プロセスは独自のメモリ空間で実行され、プロセス間通信の何らかの形式を行わない限り、子プロセスが変数に加えた変更は親に反映されません。モジュールは、この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);
于 2013-06-07T00:23:42.183 に答える