2

更新しました:

私は単体テストを持っています(Xと考えてください)。サブプロセス (Y) があります。Y は明示的にフォークしません。X は Y を実行できるようにフォークします。X は次のとおりです。

warn("Starting Y...");
my $pid;

die "failed to fork" unless($pid = fork);
unless($pid) {
    { exec "exec /usr/bin/Y"; };
    warn "failed: $!";
    _exit(0);
}

# Do something to test Y.

warn("Stopping Y...");
my $st;
do {
    kill(15, $pid);
    $st = waitpid($pid, WNOHANG);
} while ($st > 0);

warn("Y has stopped");

X から得られる出力は次のとおりです。

Starting Y... at ...
Some stuff.
Stopping Y.... at ...
Y has stopped at ...

これは、Y が信号を受信して​​停止したことを示しています。しかし、Y は停止せず、機能していない状態 (以前に "ゾンビのような" と呼んだ状態) に入ります。私が知る限り、これは完成したプロセスであり、/procからは利用できませんがkill(0, $pid)、可視化できます。ps

実際のプロセス Y では、別の話です。

sub goodbye {
    warn("Received signal");
    exit(0);
}

$SIG{TERM} = \&goodbye;
$SIG{INT} = \&goodbye;

warn("Starting server...");
my $d = HTTP::Daemon->new(
    LocalAddr => "127.0.0.1",
    LocalPort => 81,
    Reuse => 1
);

while (my $c = $d->accept) {
    # Do some stuff

    $c->close;
}

warn("Exiting...");

Y の出力にはExiting...も も表示されず、メッセージのみが表示されます。Y は機能しており、X からのすべての接続を受け入れるため、テストに合格します。止まらないだけです。Received signalStarting server

これは、X シグナル Y の前後のデバッグからの出力です。

DEBUG before kill:
root      2843  2795  0 11:23 pts/4    00:00:00 /usr/bin/perl /bin/Y
root      2844  2843  4 11:23 pts/4    00:00:00 /usr/bin/perl /bin/Y

DEBUG after kill:
root      2843  2795  0 11:23 pts/4    00:00:00 [Y] <defunct>
root      2844     1  4 11:23 pts/4    00:00:00 /usr/bin/perl /bin/Y

defunctYの状態に注意してください。2 つのプロセスがあることに注意してください。私は2つを開始しておらず、分岐していないため、HTTP::Daemon分岐したと想定しています。X を明示的に変更して、別のシグナルを送信しました。今回は、Ctrl-C を押したときのように、ハングと両方の s をSIGINT実際に停止するように送信しました。今度は Y からメッセージが届きますが、まだ機能していない状態になり、プロセスが 2 つ残っています。XYSignal received

私の質問はHTTP::Daemon、Perl とは対照的に対象としています。このカオスを引き起こすために実際にHTTP::Daemon(から派生した)は一体何をしているのですか? またその理由は何ですか? 第二に、 HTTP::Daemon が行っていることに対処するにIO::Socket::INETはどうすればよいでしょうか?Y

4

1 に答える 1

0

Okay, I may not have asked this question in the best possible way the first time round. But that doesn't mean it wasn't a valid one for which I knew that someone out there may hold the answer. But yet again, here I am, fulfilling the answer to my own question. Rather than regurgitate the answer I found, here it is in all its glory:

Strange blocking issue with HTTP::Daemon

于 2013-09-05T19:23:55.733 に答える