简体   繁体   English

HTTP :: Daemon派生未在SIGTERM上获得的子流程

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM