如何从Perl CGI程序运行长后台进程?

Flo*_*ope 2 perl cgi timeout apache2

我有一个长期运行的CGI和超时错误的问题:

超时等待CGI脚本的输出

客户端是jQuery编程的表单.用户输入一些数据并接收分析已启动的消息.除了在分析数据时带有链接的电子邮件之外,用户不希望看到更多消息.那么,此时,与客户端的连接已关闭,对吧?

在服务器端,Perl CGI脚本获取数据并执行一些C程序(使用Perl的系统)来分析它们.此过程可能需要几秒钟到几小时,具体取决于输入的数据.

然后,相同的CGI程序解析结果并向用户发送一封电子邮件,其中包含指向结果网页的链接.

因为对于某些数据,CGI可以运行几个小时我收到错误消息.

我假设增加ScriptTimeout是一个坏主意.我甚至不确定mod_cgi是否已安装.

我该怎么做才能避免这个错误?

服务器:在Mac OS X中运行的Apache2.

小智 5

我禁用了STDOUT缓冲,我尝试使用system()生成后台进程,我尝试了fork()和exec()的组合,我尝试使用后台子shell进程调用后台bash shell,你可以命名它,但没有什么可以允许父CGI进程打印输出直到后台进程完成.

这最终对我有用:

print "Content-type: text/plain\n\n";
print "Executing background process...\n";

# fork this process
my $pid = fork();
die "Fork failed: $!" if !defined $pid;

if ($pid == 0) {
 # do this in the child
 open STDIN, "</dev/null";
 open STDOUT, ">/dev/null";
 open STDERR, ">/dev/null";
 system('bash -c \'(sleep 10; touch ./test_file)\'&');
 exit;
}

print "The background task will be finished shortly.\n";
Run Code Online (Sandbox Code Playgroud)

诀窍是在子进程中关闭STDERR(通过重新打开它到/ dev/null).如果不这样做,我们的内部网络服务器就认为父进程处于活动状态,直到子进程结束.此外,无缓冲的自动刷新输出不适用于我们的网络服务器,因此我无法打印任何类型的临时状态消息.