我有一些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();
}
所有相当标准的东西。现在,我想知道是否有任何子进程崩溃(无法正确终止)。显然,如果没有打印每个子进程的最后一个语句,我可以认为存在问题。但是,我希望另一种方法可以完全退出父程序,并在子进程之一崩溃时关闭所有仍处于打开状态的子进程。这可能吗?
答案 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
为真,并且等于杀死该孩子的信号的数量。