0

フォークした子の pidlist 配列を維持し、終了時にそれらを削除したいと思います (任意の時点でフォークされたプロセスの数を制限するため)。@main::pid_list を delete または splice のいずれかで使用することでこれを行うことができると思いましたが、喜びはありませんでした。要素を正常にポップできますが、明らかに正しい pid を削除することはできません。これを処理する方法はありますか、それともまったく別の方法でこれを行う方がよいでしょうか?

#!/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

2 に答える 2

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}++;
}
于 2011-03-08T05:40:27.323 に答える
0

試す@main::pid_list = grep $_ != $child, @main::pid_list;

于 2011-03-08T05:23:13.233 に答える