更新しました:
私は単体テストを持っています(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 signal
Starting 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
defunct
Yの状態に注意してください。2 つのプロセスがあることに注意してください。私は2つを開始しておらず、分岐していないため、HTTP::Daemon
分岐したと想定しています。X を明示的に変更して、別のシグナルを送信しました。今回は、Ctrl-C を押したときのように、ハングと両方の s をSIGINT
実際に停止するように送信しました。今度は Y からメッセージが届きますが、まだ機能していない状態になり、プロセスが 2 つ残っています。X
Y
Signal received
私の質問はHTTP::Daemon
、Perl とは対照的に対象としています。このカオスを引き起こすために実際にHTTP::Daemon
(から派生した)は一体何をしているのですか? またその理由は何ですか? 第二に、 HTTP::Daemon が行っていることに対処するにIO::Socket::INET
はどうすればよいでしょうか?Y