并行分叉没有Parallel :: ForkManager?

时间:2013-06-17 17:27:48

标签: multithreading perl fork

有没有办法简单地分叉到i.g. 4个线程并在while循环中检查子节点的状态?我读了一些关于SIGCHLD(http://perldoc.perl.org/perlipc.html)的内容,但我对这些内容并不熟悉,也不知道如何使用它。顺便说一句。没有理由不使用Parallel :: ForkManager,我只是感兴趣...并尝试了类似的东西

use strict;
use warnings;
use POSIX qw/ WNOHANG /;
my @a = qw( 1 2 3 4 5 6 7 8 9 0 );
my @childs;
$#childs=4;

foreach my $a (@a){
    my $add=0;
    while(!$add){
        $add=0;
        foreach(0..$#childs){
            next if defined $childs[$_] && $childs[$_]!=0;
            $add=1;
            my $pid=fork();
            if ($pid == 0){
                &process($a);       
                exit;
            } else {    
                $childs[$_]=$pid;
                waitpid($pid,WNOHANG);              
            }           
        }
    }
}

sub process(){
    my $x = shift;  
    sleep(int(rand(10)));
    print $x."\n";
}

1 个答案:

答案 0 :(得分:1)

如果您使用F :: PM,您的代码看起来不像您正在使用的代码,因此应该引发一个红旗!

use strict;
use warnings;

use POSIX qw( _exit );

sub process {
   my ($job) = @_;
   sleep(1+int(rand(4)));
   print("$job\n");
}

my $max_children = 4;
my %children;

for my $job (0..9) {
   # Wait for the number of children to be less than the max.
   while (keys(%children) >= $max_children) {
      my $pid = wait();
      delete $children{$pid};
   }

   # Start a new child.
   if (my $pid = fork()) {
      # In parent
      ++$children{$pid};
   } else {
      # In child
      process($job);
      _exit(0);
   }
}

# Wait for remaining children to finish.
while (keys(%children)) {
   my $pid = wait();
   delete $children{$pid};
}

这基本上是P :: FM和用户代码组合的简化版本。