如何使基于CGI :: Fast的应用程序kill -HUP识别?

时间:2009-03-19 19:50:08

标签: perl fastcgi

我的应用程序可以使用Perl的CGI::Fast

基本上代码的主循环是:

while (my $cgi = CGI::Fast->new() ) {
  do_whatever( $cgi );
}

现在,我想添加杀死它的能力,但不会中断当前处理的请求。为此,我向SIGHUP添加了处理。或多或少沿着这条线:

my $sighupped = 0;
$SIG{ 'HUP' } = sub { $sighupped = 1; };
while (my $cgi = CGI::Fast->new() ) {
  do_whatever( $cgi );
  exit if $sighupped;
}

当涉及到“在处理用户请求时不打扰进程”时,哪种方法非常有效。但是,如果进程正在等待新请求,那么基于sighup的退出将不会被执行,直到它最终得到一些请求并处理它。

这有什么解决方法吗?如果HUP(或其他信号,它可以被更改)在等待请求时到达它,我想实现它以使脚本立即退出。

2 个答案:

答案 0 :(得分:1)

您可以根据处理程序的位置重新声明您的SIGnals。

如果你是在循环之外或在快速cgi轮询中进行快速cgi而不是在 事件循环终止(基本上是默认值)。如果你在事件循环逻辑中,则等待逻辑结束并终止。

原谅我目前没有编辑。

$inlogic=0;
$hupreq=0;
SIG{SIGHUP}={ exit unless($inlogic); $hupreq=1;}

while()
{
   $inlogic=1;
   function();
   $inlogic=0;
   exit if($hupreq);
}

答案 1 :(得分:1)

您可以使用eval函数的块版本和alarm函数向Fast::CGI添加超时。在下面的代码中,我设置了五秒超时。如果它超时,它将返回到循环的开始,这将检查$continue是否已被设置为零。如果没有那么我们就开始一个新的CGI::Fast对象。这意味着,如果代码在等待新的HUP对象时代码开始停止之前发送CGI::Fast,则最多会持续五秒钟(超时对其余部分没有影响)循环)。

my $continue = 1;
$SIG{HUP} = sub { $continue = 0 };
while ($continue) {
    my $cgi;
    eval {
        local $SIG{ALRM} = sub { die "timeout\n" };
        alarm 5; #set an alarm for five seconds
        $cgi = CGI::Fast->new;
        alarm 0; #turn alarm off
    };
    if ($@) {
        next if $@ eq "timeout\n"; #we will see the HUP signal's change now
        #died for a reason other than a timeout, so raise the error
        die $@;
    }
    last unless defined $cgi; #CGI::Fast has asked us to exit
    do_stuff($cgi);
}

#clean up