“Maximal count of pending signals (120) exceeded”是什么意思?

7
我的Perl Web应用程序在Apache mod_fastcgi下运行时,经常出现以下错误:

在第119行超过了挂起信号的最大计数(120)。

我看到这种情况发生在文件上传方面,但我不确定这是唯一发生的时间。在我得到这个错误之前(或可能之后),我还会收到一个SIGPIPE信号。
有什么想法吗?
编辑:谢谢大家的建议。有人问第119行是什么。抱歉,我应该把它放进去的。它在一个代码块中,我在上传文件时运行病毒检查器。我不是每次都会得到这个错误,只是偶尔。
if(open VIRUS_CK, '|/usr/local/bin/clamscan - --no-summary >'.$tmp_file) {

  print VIRUS_CK $data; // THIS IS LINE 119

  close VIRUS_CK;

  if (($? >> 8) == 1) {

    open VIRUS_OUTPUT, '<'.$tmp_file;
    my $vout = <VIRUS_OUTPUT>;
    close VIRUS_OUTPUT;
    $vout =~ s/^stdin:\s//;
    $vout =~ s/FOUND$//;


    print STDERR "virus found on upload: $vout\n";
    return undef, 'could not accept attachment, virus found: '.$vout;
  }
  unlink($tmp_file);
}

显而易见的问题:第119行是什么? - ysth
当Perl出现这种情况时,它会退出还是只是丢失那些信号? - mcr
2个回答

7
这意味着操作系统向Perl发送的信号比它处理的速度快,已经达到饱和点。在操作之间,Perl会保存要处理的信号,然后在有机会时再处理它们。由于Perl没有喘息的机会,就会收到太多的信号而出现此错误。这是一个致命错误,因此您的Perl进程将终止。
解决方案是找出生成如此多信号的原因。更多详细信息请参见此处
更新:我的原始答案有些不准确,说生成一个新的Perl进程是问题的一部分,实际上并不是。我根据下面@ysth的评论进行了更新。

1
与启动新进程无关;Perl捕获信号并将它们保存以在操作之间的安全点分派,而此错误表示在该安全点之前接收到了大量信号。 - ysth
你有没有关于如何找出信号来自哪里的想法? - NXT
建议检查Apache中FastCGI模块的日志记录或调试选项。 - mctylr

2
我会手舞足蹈,因为我很久没有使用mod_fastcgi了,而且已经有一段时间没有看它的文档了。
我猜你的Perl模块是非forking的,但运行起来需要一些时间,以至于客户端关闭需要一些时间来处理。请参阅FastCGI Apache模块mod_fastcgi下的注意事项,了解FastCGI使用的信号以及程序可能希望如何处理这些信号,包括SIGPIPE

我对 SIGPIPE 除了向 STDERR 输出收到 SIGPIPE 的信息以外什么都不做。反正我也不确定如何关闭一个正在处理的请求。 这种情况下,我应该设置一个标志并在任何长时间运行的循环中定期检查该标志吗(尽管我没有任何这样的循环)? - NXT
在任何长时间运行的循环中(尽管我没有任何这样的循环),我怀疑运行clamscan并等待其结果是造成长时间延迟的原因。如果最终用户由于等待病毒扫描器运行而不耐烦而中止FastCGI脚本,则会生成SIGPIPE信号,据我所知。这也会阻塞其他等待Perl脚本完成(即等待病毒扫描器)的Web请求,因此如果那些Web用户还“停止”或中止他们的连接,则还会产生SIGPIPE信号。--请谨慎对待这一切,已经有一段时间了。 - mctylr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接