2011-11-29 5 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 '을 (를) 사용하십시오'; 내 $ files4에 대해 (4 => @ 파일) @ {$ files4}로 뭔가를하십시오. ' –

1

내가 그룹 배열하고,하자 아이가 처리 할 것이라고 그룹

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

이 여전히 100 개 프로세스를 생성하는
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 
} 
관련 문제