由SIGCHLD终止的Perl睡眠
输出:由SIGCHLD终止的Perl睡眠,perl,Perl,输出: #!/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; } $l
#!/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";
}
上面是我的Perl脚本。输出是正确的,但奇怪的是,它在最后一次输出后立即打印I am parent,child pid:11839
。为什么sleep 1000
没有任何效果?请始终使用严格的和使用警告
,并在定义点使用my
声明您的符号。这一点尤其适用于请求帮助时,因为这些措施可能会暴露出容易被忽略的简单错误
sleep
通过使用setitimer
在指定的间隔后请求SIGALRM
,然后pause
暂停进程,直到收到信号为止
但是如果先出现一个SIGCHLD
,这也会唤醒进程
无法设置信号掩码以防止出现这种情况,否则将无法维修SIGCHLD
,这是:“如果进程接收到信号,可能会中断”。整个要点是允许信号处理程序运行。如果还没到起床的时间,就回去睡觉吧
I'm child, pid=11839.
where is here,11839
I am parent, child pid : 11839
使用时间::雇佣qw(时间睡眠);#可选。
子未调整睡眠(美元){
我的$sleep_til=时间+$\u[0];
对于(;;){
我的$sleep\u dur=时间-$sleep\u til;
最后,如果$sleep_dur这不是sleep
的实现方式,在这十年来的大多数操作系统/Perl中,或者在内核中。请参阅@ZacB:我正在查看Perl v5.24的C源代码,您的评论似乎不公平。请添加一个答案,正确定义Perlsleep
调用在您眼中的工作方式。注意,它没有调用usleep
是您链接到的。@ZacB那么它是如何实现的?我想知道,如果不是这样的话。您提供的链接只是usleep
的手册页,它没有告诉我Perl是如何实现自己的。Perl的页面实际上暗示了setitimer
。请注意,usleep
来自前面提到的模块ed似乎没有使用这个系统调用(请参阅模块的文档)。您能提供一些文档或指针吗?请参阅strace perl-e'sleep(10)“
。在我使用过的平台上,不会调用alarm
或setitimer
,也不会发送信号;相反,会调用nanosleep
和朋友。此外,因为每个进程只有一个alarm
/setitimer
时钟(至少在Unix中),实现带有报警的睡眠
会破坏用户设置的报警,而这不会发生;请参阅time perl-e“报警(2);睡眠(10);”
。
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);
}
}