Perl:为什么这会创建数以千计的子进程?

时间:2010-08-18 01:04:48

标签: perl process fork

因此,当我运行此代码时,它似乎可以分叉炸弹系统,你们可以帮助我吗?我想做的就是为每个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 个答案:

答案 0 :(得分:3)

您的代码应该只创建三个孩子。如果您看到正在创建一堆子项,那么您运行的是不同的代码(或者罪魁祸首是appWatch而不是您的代码)。在一个稍微不相关的说明中,有几件事你应该采取不同的做法:

  1. fork有三个可能的返回值,而不是两个
  2. 你必须收拾你的孩子或设置系统以便为你收获
  3. 如果您不想返回代码,则应使用exec而不是系统
  4. 如果您不希望shell使用参数执行操作,则应使用systemexec的多参数版本而不是一个参数版本。
  5. 以下是我的代码版本:

    $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 :(得分:1)

使用

$ 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]