Linux - 没有退出子进程的Perl fork循环

时间:2016-10-22 09:47:11

标签: perl fork

我是fork概念的新手。我正在尝试使用fork循环的简单脚本,期望执行两次但最终会发生3次。是因为我没有退出子进程吗?你能澄清一下吗

脚本:

#!/usr/bin/perl

open(my $fh, '>', 'report.txt');
print $fh "before invoke fork \n";
close $fh;

@list = (1, 2);

foreach $a (@list){

    if($pid = fork){
       open(my $fh, '>>', 'report.txt');
       print $fh "Parent process! $a $pid\n";
       close $fh;

    }else {
       open(my $fh, '>>', 'report.txt');
       print $fh "Child process $a $pid\n";
       close $fh;
    }
}

输出:

在调用fork之前 我的第二份报告由perl 1 1808生成 我的第二份报告由perl 2 1809生成 我的thrid报告由perl 2 0生成 我的thrid报告由perl 1 0生成 我的第二份报告由perl 2 1810生成 我的thrid报告由perl 2 0生成

2 个答案:

答案 0 :(得分:2)

这是因为fork()这两个进程从开始的点完全相同

所以'孩子1'将继续运行,并继续循环,并运行迭代2'。

所以父会分叉两次,子1会分叉一次,子2 - 因为它是最后一次循环迭代 - 根本不会分叉。

我建议你真的应该考虑Parallel::ForkManager因为它简化了很多。还有 - 启用use strict;use warnings。并且不使用单字母变量,尤其不是$a

这里有一些example code如何使用Parallel::ForkManager

然而,要解决您的问题 - 在子节中坚持last将导致它摆脱循环。

答案 1 :(得分:1)

您没有在循环中等待子进程。关于fork in循环有一个很好的解释:

http://perlmaven.com/fork

也有手册。

http://perldoc.perl.org/perlfork.html

尽量小心叉子中的所有可能性。对待问题很重要!一种简单,好的和推荐的实施方式:

use strict;
use warning;
use Carp qw/confess/;
my $pid = fork;

if(!defined($pid)){
  confess "\nWhy you hates me, O.S.? Why?\nANSWER: $!\n\n";
}
elsif($pid == 0){
  #Child process. Do something and exit
}
else{
  #Parent process
  waitpid $pid,0; 
}

此示例中未描述其他相关功能。要详细了解相关信息,请查看上面链接的manual

结帐Parallel::ForkManager