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出力は正しいのですが、最後の出力の直後に印刷されるという奇妙な点が 1 つあります。なぜ効果がなかったの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

常に use strictuse warningsを使用してシンボルをmy定義してください。これは、特に助けを求めている場合に当てはまります。これらの対策によって、見過ごされがちな単純なバグが明らかになる可能性があるためです。

sleepを使用して、指定された間隔の後setitimerに を要求し、シグナルを受信するまでプロセスを一時停止することによって実装されます。SIGALRMpause

ただし、 aSIGCHLDが最初に来ると、これもプロセスを起こします。

これを防ぐためにシグナルマスクを設定することはできませんSIGCHLD

于 2012-08-23T10:35:58.437 に答える