2011-11-29 7 views
5

私は何百というファイル名を配列に持っています。私は、配列内の4つのファイルごとに子プロセスを作成し、その子プロセスに4つのファイルのそれぞれにいくつかの処理をさせたいと思います。 (100個のファイルがあるので、25個のプロセスを作成します)Perlでfork()を使うには?

フォークがあるときに行が処理される順序を理解するのに問題があります。私はこのような何かを行うことが考えていたが、私は立ち往生しています:

foreach $file (@files) { 
if ($f++ % 4 == 0) { 
    my $pid = fork(); 

    if ($pid) { 
    push(@childs, $pid); 
    } 
    elsif ($pid == 0) { 
    ... do stuff to $file ... 
    } 
} 

私はこれが正しいとは思わない、と私は、誰かが正しい方向に私を指すことができます願っています。ありがとう。

答えて

11

forkを使用している問題に加えて、@filesアレイを4つのファイルの小さなセットに分割することも問題があるようです。たぶん、このような何か:

for (my $i = 0; $i < @files; $i += 4) { 

    # take a slice of 4 elements from @files 
    my @files4 = @files[$i .. $i + 3]; 

    # do something with them in a child process 
    if (fork() == 0) { 
     ... do something with @files4 ... 
     exit; # <--- this is very important 
    } 
} 

# wait for the child processes to finish 
wait for 0 .. @files/4; 
+1

'(私の@ files4 =スプライス(@files、0、4)){'(@filesを破壊する、しかし)しながら、 – ysth

+0

'$ i'を4ずつインクリメントしているので、スライスするときに4を掛ける必要はありません。 – itzy

+2

'List :: Gen 'by';を使用してください。私の$ files4のために(4 => @ファイル){@ $ files4で何かする} ' –

1

これはまだ100個のプロセスを作成することを私は配列へのグループだろう、と子供はそのグループ

my $group = [] 
foreach my $file (@files) { 
    push @$group, $file; 

    if(scalar(@$group) % 4 == 0) { 
     my $pid = fork; 
     die "Unable to fork!" unless defined $pid; 
     push @childs, $pid if $pid; 
     children_work($group) unless $pid; 
     $group = []; 
    }   
} 

sub children_work { 
    my $group = shift; 

    // child, work with $group 
    exit(0); 
} 
3

使用Parallel::ForkManager

use Parallel::ForkManager qw(); 

my $pm = Parallel::ForkManager->new(int(@files/4)); 
for my $file (@files) { 
    my $pid = $pm->start and next; 

    ... do something with $file ... 

    $pm->finish; # Terminates the child process 
} 

を処理させるノート、単にそれを同時に25に制限します。

あなたが本当に唯一の25のプロセスをしたい場合は、以下を使用することができます。

use List::Util   qw(min); 
use Parallel::ForkManager qw(); 

my $pm = Parallel::ForkManager->new([email protected]); 
while (@files) { 
    my @batch = @files[0..min(4, $#files)]; 
    my $pid = $pm->start and next; 

    for my $file (@batch) { 
     ... do something with $file ... 
    } 

    $pm->finish; # Terminates the child process 
} 
関連する問題