Perl - 负责分叉

时间:2012-02-09 07:44:00

标签: perl fork

我新发现了Perl forking,我很爱。但有一点让我担心 - 如果我只是左右分离流程,肯定这会在某个地方引起一些问题。是否有合理的检查可以确保我的小应用程序不会占用我机器的所有资源?

获取此示例代码:

foreach my $command (@commands) {
   my $pid = fork();
   if (!$defined $pid) {
     #Fork failed. Do something.
   } elsif ($pid == 0) { #This is the child.
      system($command);
      exit(0)
   }
}

while (wait() != -1) {} #wait() will be -1 when the last child exits.

所以这样可以正常工作,并产生一个处理每个命令的进程。它将全部并行发生,如果这些命令是完全独立的,那就太棒了。

如果我突然有5,000多个命令可以运行怎么办?不假思索地分开那么多流程是不明智的。那么应该实施什么样的检查,以及如何实施?

4 个答案:

答案 0 :(得分:7)

此外,如果您担心同时产生过多的分叉进程,可以限制它们。

自己滚动(使用队列来保存“to fork”),或者更好的是,使用Parallel::ForkManager模块,它允许你通过构造函数参数限制同时的forks。

use Parallel::ForkManager;
$pm = new Parallel::ForkManager($MAX_PROCESSES);

请注意,ForkManager还将通过提供的“wait *”API为您收集已结束的子进程

答案 1 :(得分:3)

当孩子退出时,它会向父母发送SIG_CHLD。你想要收获这些,就好像你不会这样,他们将成为流程表中的僵尸,直到你脚本结束时最后一次调用wait

Chapter 16 of O'Reilly's Perl Cookbook on Google books提供了大量有关此内容的信息。基本上,你需要在你抚养孩子时增加一个计数器,并在你收割它们时减少它,而不是将新的计数器超过目前正在运行的孩子的合理最大值。

至于“合理的最大值”是什么......取决于硬件,以及这些分叉进程正在做什么。这个问题没有静态的答案,除了说测试你正在做什么,看看对机器的性能影响。最好在营业时间内。告诉系统管理员你在做什么。他/她甚至可能会有一些建议。

答案 2 :(得分:1)

为了确保您不会产生比系统可以有效处理的更多进程,您可以使用Parallel::ForkManager等模块

答案 3 :(得分:0)

产生(分叉)系统可以支持的多个进程称为fork bomb。当您的进程表变得饱和并且内存和CPU耗尽时,您的系统可能会冻结或崩溃。在Linux系统上,ulimit命令应显示允许的最大用户进程数。您可以(应该)为您的系统适当地设置它。分叉以指数方式创建流程。因此,这个片段创建了四个进程,无休止地消耗CPU直到被杀死 - 一个令人讨厌的微小炸弹:

perl -e 'fork; fork; 1 while {}'