[英]HTTP::Daemon forks sub processes that aren't reaped on SIGTERM
Updated: 更新:
I have a unittest (consider it X). 我有一个单元测试(考虑X)。 There is a subprocess (Y).
有一个子流程(Y)。 Y does not explicitly fork.
Y不会明确分叉。 X forks so it can exec Y. Here is X:
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");
The output I get from X is: 我从X得到的输出是:
Starting Y... at ...
Some stuff.
Stopping Y.... at ...
Y has stopped at ...
This would suggest Y has received the signal and stopped. 这表明Y已收到信号并停止。 But Y doesn't stop, it goes into a defunct state (what I previously referred to as "zombie like").
但是Y不会停止,它会进入失效状态(我以前称为“僵尸状”)。 As far as I can tell, it is a finished process, not available to
kill(0, $pid)
but visible through ps
and /proc. 据我所知,这是一个完成的过程,无法
kill(0, $pid)
但可以通过ps
和/ proc看到。
In the actual process Y, it is a different story: 在实际过程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...");
I never see the Exiting...
nor the Received signal
in the output for Y, only the Starting server
message. 我从没看到Y的输出中的
Exiting...
或Received signal
,只有Starting server
消息。 Y is functioning and accepts all connections from X, thus passes the tests; Y正在运行,并接受来自X的所有连接,从而通过了测试; it just fails to stop.
它只是无法停止。
This is the output from some debug before and after X signals Y. 这是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
Note the defunct
state of Y and notice that there are two processes. 注意Y的
defunct
状态,并注意有两个过程。 I didn't start two and it doesn't fork, so I am assuming HTTP::Daemon
forked. 我没有从两个开始,也没有派生,所以我假设
HTTP::Daemon
分叉了。 I explicitly modified X to send a different signal. 我明确修改了X以发送不同的信号。 This time I sent
SIGINT
, like when I hit Ctrl-C and it actually stops the hung X
and both Y
s. 这次我发送了
SIGINT
,就像我按Ctrl-C一样,它实际上停止了挂起的X
和两个Y
I get the Signal received
message from Y this time, but it stills goes into a defunct state and there are still two processes. 这次我从Y
Signal received
消息,但是它仍然进入已失效状态,并且仍然有两个过程。
My question is targeted at HTTP::Daemon
as opposed to Perl. 我的问题针对的是
HTTP::Daemon
,而不是Perl。 What on earth is HTTP::Daemon
(derived from IO::Socket::INET
) actually doing to cause this chaos and why? HTTP::Daemon
(源自IO::Socket::INET
)到底在做什么,导致这种混乱,为什么? Secondly, how do I adapt Y
to cope with what HTTP::Daemon is doing? 其次,如何使
Y
适应HTTP :: Daemon的工作?
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 HTTP :: Daemon的奇怪阻止问题
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.