1

有没有办法简单地分叉到 ig 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";
}
4

1 回答 1

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 和用户代码组合的简化版本。

于 2013-06-17T18:41:05.183 回答