3
#!/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任何效果?

4

2 回答 2

8

这被记录在案:“如果进程收到信号,可能会被中断”。重点是允许信号处理程序运行。如果还没到醒来的时间,就回去睡觉吧。

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);
    }
}
于 2012-08-23T13:50:33.867 回答
2

Please always use strict and use warnings, and declare your symbols using my at their point of definition. This applies especially when you are asking for help, as these measures can reveal simple bugs that are otherwise easily overlooked

sleep is implemented by using setitimer to request a SIGALRM after a specified interval, and then pause to suspend the process until it gets the signal.

But if a SIGCHLD comes first this will also wake the process.

The signal mask cannot be set to prevent this as otherwise the SIGCHLD wouldn't get serviced

于 2012-08-23T10:35:58.437 回答