2011-03-08 24 views
0

我想维护一个我已分叉的子组的pidlist数组,然后在它们退出时删除它们(以限制我在任何给定的分叉进程数时间)。我认为我可能很聪明,通过在删除或拼接中使用@main :: pid_list来做到这一点,但没有喜悦。我可以成功地弹出一个元素,但显然它不会删除正确的pid。任何想法如何处理,或者我会更好地做这个完全不同的方式?从信号处理函数(Perl)中的main ::更新数组

#!/usr/bin/perl -w 
use POSIX ":sys_wait_h"; 
use Data::Dumper; 

# Only allow 5 processes running at a time 

sub REAPER { 
    my $child = shift; 
    while (($child = waitpid(-1, WNOHANG)) > 0) { 
     # Need to remove child from pidlist here 
     #pop(@main::pid_list);      #This works 
     #delete($main::pid_list[$child]);   #This does not 

    } 
    $SIG{CHLD} = \&REAPER; 
} 

@pid_list =(); 
@files = (1 .. 20); 

foreach my $file (@files) { 
    my $processed = 'false'; 
    while ($processed eq 'false') { 

     print "Working on file: $file\n"; 
     $SIG{CHLD} = \&REAPER; 
     if (scalar(@pid_list) < 5) { 
      $pid = fork(); 
      if ($pid == 0) { 
       print "$$: Child Processing file #" . $file . "\n"; 
       sleep(10); 
       print "$$: Child done processing file #" . $file . "\n"; 
       exit(0); 
      } 
      push(@pid_list, $pid); 
      print Dumper(@pid_list); 
      $processed = 'true'; 
     } 
     sleep(1); 
    } 
} 

# Since we are at the end we need to wait for the last process to end 
print "PID: $$ End of parent program\n"; 

exit 0; 
+4

看起来像一个很好的地方,使用并行:: ForkManager – ysth 2011-03-08 07:26:36

回答

5

使用哈希表,而不是阵列。

sub REAPER { 
    my $child = shift; 
    while (($child = waitpid(-1, WNOHANG)) > 0) { 
     # Need to remove child from pidlist here 
     delete $main::pid_list{$child}; 
    } 
    $SIG{CHLD} = \&REAPER; 
} 

... 

if ((scalar keys %main::pid_list) < 5) { 
    ... 
    if ($pid != 0) { 
     ... 
     exit(0); 
    } 
    $main::pid_list{$pid}++; 
} 
+0

这是没有必要使用'scalar'那里,'<'已经暗示标量上下文。 – cjm 2011-03-08 06:53:16

+0

完美的作品 - 谢谢袜子傀儡! – OregonJeff 2011-03-08 15:30:15

0

尝试@main::pid_list = grep $_ != $child, @main::pid_list;