【发布时间】:2014-03-13 10:43:52
【问题描述】:
如果使用 Perl FCGI,如何在不使用 exit 的情况下结束脚本。在搜索了几天后,我发现唯一的解决方案是跳转到主脚本中的标签处。下面是主index.fcgi的代码。
$fcgi_requests = 0; # the number of requests this fcgi process handled.
$handling_request = 0;
$exit_requested = 0;
$app_quit_request = 0; # End the application but not the FCGI process
# workaround for known bug in libfcgi
while (($ignore) = each %ENV) { }
$fcgi_request = FCGI::Request();
#$fcgi_request = FCGI::Request( \*STDIN, \*STDOUT, \*STDERR, \%ENV, $socket);
sub sig_handler {
my ($callpackage, $callfile, $callline) = caller;
if ($app_quit_request) {
$app_quit_request = 0;
goto ABORTLABEL;
}
$exit_requested = 1;
exit(0) if !$handling_request;
}
$SIG{USR1} = \&sig_handler;
$SIG{TERM} = \&sig_handler;
$SIG{PIPE} = 'IGNORE';
#The goal of fast cgi is to load the program once, and iterate in a loop for every request.
while ($handling_request = ($fcgi_request->Accept() >= 0)) {
process_fcgi_request();
$handling_request = 0;
last if $exit_requested;
#exit if -M $ENV{SCRIPT_FILENAME} < 0; # Autorestart
}
$fcgi_request->Finish();
exit(0);
#=========================================================#
sub process_fcgi_request() {
$fcgi_requests++;
# dispatch current request
my_app();
$fcgi_request->Finish();
}
#=========================================================#
# let it think we are done, used by abort
ABORTLABEL:
$fcgi_request->Finish();
#=========================================================#
主要请求是我想停止从子 insidi 模块内部执行程序,这些模块可能会被长深度调用,例如在帐户模块中的登录函数内部。 当然我不能使用 exit 因为它会终止 fcgi 进程,我尝试了所有错误并抛出并尝试模块都使用 die 这也结束了进程。当然我可以使用每个 sub 的返回,但这需要为 fcgi 重写整个程序。
【问题讨论】: