HTTP :: Daemon forks不在SIGTERM上获取的子进程

时间:2013-09-05 11:33:34

标签: perl http-daemon

更新:

我有一个单元测试(考虑它是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并没有停止,它进入了一个已经不复存在的状态(我之前称之为“像僵尸一样”)。据我所知,这是一个已完成的流程,kill(0, $pid)无法使用,但可通过ps和/ proc查看。

在实际过程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...Received signal,只看到Starting server消息。 Y正在运行并接受来自X的所有连接,从而通过测试;它只是没有停止。

这是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

注意Y的defunct状态,注意有两个进程。我没有开始两个,它没有fork,所以我假设HTTP::Daemon分叉。我明确修改了X以发送不同的信号。这次我发送了SIGINT,就像我按下Ctrl-C一样,它实际上停止了挂起的XY。这次我收到来自Y的Signal received消息,但它仍然处于一个已经不存在的状态,仍然有两个进程。

我的问题针对的是HTTP::Daemon,而不是Perl。究竟是什么HTTP::Daemon(源自IO::Socket::INET)实际上是为了引起这种混乱?为什么?其次,我如何调整Y以应对HTTP :: Daemon正在做什么?

1 个答案:

答案 0 :(得分:0)

好的,我可能没有在第一轮以最好的方式提出这个问题。但这并不意味着它不是一个有效的,我知道那里的人可能会得到答案。但是,我在这里,实现了我自己的问题的答案。而不是反复我发现的答案,这里有它的全部荣耀:

Strange blocking issue with HTTP::Daemon