2

我有一个简单的 perl 脚本,它调用一个从浏览器调用时总是“挂起”的 shell 脚本。我只想在 20 秒后强制暂停。当我在命令行中运行它时,没有问题。但是当我从浏览器执行此操作时,脚本已执行但从未完成加载。所以我没有得到页面上的输出。如果我在命令行中杀死 -9 进程,则浏览器完成加载,并在浏览器中显示内容。

我做了很多研究,似乎 Web 服务器正在等待 shell 脚本完成,因为 shell 脚本仍然有一个标准输出的打开文件句柄。

这是我的代码。

#!/usr/bin/perl

use strict;
use warnings;

use CGI;

my $q = new CGI;

print $q->header;

my $timeout = 10;
my $pid = fork;

if ( defined $pid ) {
     if ( $pid ) {

         # this is the parent process
         local $SIG{ALRM} = sub { die "TIMEOUT" };

         alarm 10;

         # wait until child returns or timeout occurs    
         eval {
             waitpid( $pid, 0 );
         };

         alarm 0;

         if ( $@ && $@ =~ m/TIMEOUT/ ) {
            # timeout, kill the child process
            kill 9, $pid;
         }
    }
    else {
         # this is the child process
         # this call will never return. Note the use of exec instead of system
         exec "/opt/bea/domains/fsa/scripts/start.sh";
    }
}
else {
     die "Could not fork.";
}

在一定时间后,无论 shell 脚本的状态如何,如何强制页面完成加载。

4

1 回答 1

0

问题是在您的脚本完成后,网络服务器仍在等待所有创建的(甚至是您创建的)子节点完成。如何处理它的最佳方法是使用setsid. 或者你甚至可以尝试“双叉把戏”,你从孩子那里分叉,然后再分叉。之后,第一个孩子将退出,第二个孩子成为孩子 if init。还要确保(在这两种情况下)在孩子中你这样做:

close STDIN;
close STDOUT;
close STDERR;
于 2012-10-23T09:23:53.853 回答