Perl:为什么这会创建数千个子进程?

发布于 2024-09-14 23:18:54 字数 1000 浏览 3 评论 0原文

所以当我运行这段代码时,它似乎对系统进行了分叉炸弹,你们能帮我吗?我想要做的就是为每个 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();

So when I run this code it seems to fork bomb the system can you guys help me out? All I want to do is start a thread for each one of the appWatch domains and enviroments.

#!/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();

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

洛阳烟雨空心柳 2024-09-21 23:18:54

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

  1. fork 有三个可能的返回值,而不是两个,
  2. 您必须收获您的孩子或设置系统为您收获
  3. 它们应该使用 exec 而不是 system 如果您不想返回代码,
  4. 则应该使用 systemexec 的多参数版本如果您不希望 shell 对参数执行某些操作,请选择单参数版本。

这是我的代码版本:

$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;
}

Your code should only create three children. If you are seeing a bunch of children being created then you are running different code (or the culprit is appWatch not your code). On a slightly unrelated note, there are a couple things you should probably be doing differently:

  1. fork has three possible return values, not two
  2. you must reap your children or set the system up to reap them for you
  3. you should use exec instead of system if you don't want to return to the code
  4. you should use the multiple argument version of system and exec instead of the one argument version if you don't want the shell to do stuff with the arguments.

Here is my version of your code:

$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";
        }
}

You updated version of the code shows what happened. Your child does not exit. Here is how I would write your code:

#!/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;
}
昇り龍 2024-09-21 23:18:54

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

With

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

running on

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

I get no fork bomb, just an unexciting Cartesian product:

$ ./prog.pl 
[-d][domains][-e][enviromentA]
[-d][domains][-e][enviromentB]
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文