Perl: Почему это создает тысячи дочерних процессов? - PullRequest
2 голосов
/ 18 августа 2010

Так что, когда я запускаю этот код, кажется, что система работает, вы, ребята, можете мне помочь?Все, что я хочу сделать, - это запустить поток для каждого домена и среды appWatch.

#!/usr/bin/perl
#
#
#       Starts the mass processes to watch each directory & enviroment.
#
#
#
###################################################################################
use strict;
use warnings;
use POSIX 'setsid';
setsid();
my @domains = (qw(austin batman luke heman drevil joker skeltor drevil goodguy badguy));
my @envs = (qw(qa dev));
        foreach my $env (@envs){
                foreach my $guy (@domains){
                        unless(my $pid = fork()){
                                system("echo $env.$guy");
                                system("sleep 10 ");
                                #system("./appWatch -d $guy -e $env");
                                open PID, ">>pid.lock";
                                print PID $$ . "\n";
                                print "$$ is Parent, $pid is child";
                }
        }
}
                wait();

Ответы [ 2 ]

3 голосов
/ 18 августа 2010

Ваш код должен создавать только трех детей.Если вы видите, как создается группа детей, значит, вы запускаете другой код (или виновник appWatch не ваш код).На немного не связанной ноте есть пара вещей, которые вы, вероятно, должны делать по-другому:

  1. fork имеет три возможных возвращаемых значения, а не два
  2. , которые вы должны пожинать своим детям илинастройте систему так, чтобы она получала их для вас
  3. вы должны использовать exec вместо системы, если вы не хотите возвращаться к коду
  4. вы должны использовать версию с несколькими аргументами system и exec вместо версии с одним аргументом, если вы не хотите, чтобы оболочка работала с аргументами.

Вот моя версия вашего кода:

$SIG{CHLD}  = "IGNORE"; #auto-reap the children
my @domains = qw(domains);
my @envs    = qw(enviromentA enviromentB);
for my $env (@envs){
        for my $guy (@domains){
                die "could not fork: $!" unless defined(my $pid = fork);
                next if $pid;
                exec "./appWatch", "-d", $guy, "-e", $env;
                die "exec must have failed";
        }
}

Обновленная версия кода показывает, что произошло.Ваш ребенок не выходит.Вот как бы я написал ваш код:

#!/usr/bin/perl
# Starts the mass processes to watch each directory & enviroment.

use strict;
use warnings;
use POSIX 'setsid';
setsid();

my @domains = qw(
    austin  batman luke    heman
    drevil  joker  skeltor drevil
    goodguy badguy
);
my @envs = qw(qa dev);

my @pids;
for my $env (@envs){
    for my $guy (@domains){
        die "could not fork: $!" unless defined(my $pid = fork);
        if ($pid) {
            push @pids, $pid;
            next;
        }
        print "$env.$guy\n";
        sleep 10; #FIXME: I don't know if you really need this
        #exec will replace the child process with appWatch
        exec "./appWatch", "-d", $guy, "-e", $env;
        die "exec failed for some reason";
    }
}
for my $pid (@pids) {
    waitpid $pid, 0;
}
1 голос
/ 18 августа 2010

С

$ cat appWatch 
#! /usr/bin/perl -l
print "[", join("][" => @ARGV), "]";

работает на

$ uname -a
Linux mybox 2.6.32-24-generic #39-Ubuntu SMP Wed Jul 28 05:14:15 UTC 2010 x86_64 GNU/Linux

Я не получаю fork бомбу, только неинтересный декартовский продукт:

$ ./prog.pl 
[-d][domains][-e][enviromentA]
[-d][domains][-e][enviromentB]
...