#!/usr/bin/perl
use POSIX ":sys_wait_h";
$SIG{CHLD} = \&REAPER;
sub REAPER {
my $pid;
while (($pid = waitpid(-1, WNOHANG)) > 0) {
print "where is here,$pid\n";
}
}
sub child {
print "I'm child, pid=$$.\n";
sleep 2;
}
$lid = fork();
if ($lid == 0) {
&child;
exit;
} else {
sleep 1000;
print "I am parent, child pid : $lid\n";
}
输出:
I'm child, pid=11839.
where is here,11839
I am parent, child pid : 11839
以上是我的Perl脚本。输出是正确的,但奇怪的是它在最后一次输出后立即打印I am parent, child pid : 11839
。为什么sleep 1000
没有任何效果?
答案 0 :(得分:8)
这是documented:“如果进程收到信号,可能会中断”。重点是允许信号处理程序运行。如果没时间醒来,就回去睡觉吧。
use Time::HiRes qw( time sleep ); # Optional.
sub unint_sleep($) {
my $sleep_til = time + $_[0];
for (;;) {
my $sleep_dur = time - $sleep_til;
last if $sleep_dur <= 0;
sleep($sleep_dur);
}
}
答案 1 :(得分:2)
请始终 use strict
和use warnings
,并在定义时使用my
声明您的符号。这尤其适用于您寻求帮助的情况,因为这些措施可以揭示容易被忽视的简单错误
sleep
是通过使用setitimer
在指定的时间间隔后请求SIGALRM
,然后pause
暂停进程直到获得信号来实现的。
但如果SIGCHLD
首先出现,这也会唤醒这个过程。
无法设置信号掩码以防止此情况,否则SIGCHLD
将无法获得服务