perl fork()如何检查孩子是否崩溃

时间:2018-11-08 11:12:39

标签: perl fork

我有一些Perl代码,可以生成许多子进程。基本代码如下:

 my $forked = 0;
 my $err = 0;
 my $Processes_To_Use_After_Calc=10;     
 print "Parent ($$) has started\n";
 for my $ispawn (1 .. $Processes_To_Use_After_Calc){
    my $child_pid = fork();
    die "Cannot fork: $!" if !defined $child_pid; # system overload
    if(defined $child_pid && $child_pid > 0) {
        ## Parent
        $forked++;
    } elsif(defined $child_pid){
        #
        # Here some calculations are performed
        #
        print "Child $$ has finished (number $ispawn) \n";
    }
}
for(1..$forked) {
    my $child_pid = wait();
}

所有相当标准的东西。现在,我想知道是否有任何子进程崩溃(无法正确终止)。显然,如果没有打印每个子进程的最后一个语句,我可以认为存在问题。但是,我希望另一种方法可以完全退出父程序,并在子进程之一崩溃时关闭所有仍处于打开状态的子进程。这可能吗?

2 个答案:

答案 0 :(得分:6)

wait$?

  

系统上的行为类似wait(2):它等待子进程终止并返回已故进程的pid,如果没有子进程,则返回-1。状态将以$?和$ {^CHILD_ERROR_NATIVE}的形式返回。

所以

my $child_pid = wait();

if    ( $? == -1  ) { die "wait failed: $!\n"; }
elsif ( $? & 0x7F ) { warn "Child $child_pid killed by signal ".( $? & 0x7F )."\n"); }
elsif ( $? >> 8   ) { warn "Child $child_pid exited with error ".( $? >> 8 )."\n"); }
else                { print "Child $child_pid exited successfully\n"; }

如果程序确实崩溃了,您将得到Child killed by signal 11,即SIGSEGV

如果抛出未捕获的异常,则可能会得到Child exited with error XXX。确切值会因程序而异,可能毫无意义。默认情况下,Perl在未捕获的异常上使用$! || ($? >> 8) || 255作为退出值。

答案 1 :(得分:2)

根据wait的文档:

  

就像系统上的wait(2)一样:它等待子进程执行                  终止并返回已故进程的pid,如果返回,则返回“ -1”                  没有子进程。状态以$返回?和                  “ $ {^ CHILD_ERROR_NATIVE}”。请注意,返回值“ -1”可以                  意味着子进程被自动获取,因为                  在perlipc中进行了描述。

如果您的孩子被信号杀死,则$? & 0x7F为真,并且等于杀死该孩子的信号的数量。