如何使用mod perl运行后台进程

问题描述:

我正在使用perl以XML格式返回数据集。现在我遇到了一种情况,我需要在将数据集发送到客户端后进行一些清理。但有些地方,在mod perl和Apache的链中,输出会一直持续到我的方法返回。如何使用mod perl运行后台进程

我试图用类似命令清除缓冲区。

$| =1; 
STDOUT->flush(); # flush the buffer so the content is sent to the client and the finish hook can carry on, with out delaying the return. 
if ($mod_perl_io){ 
    $mod_perl_io->rflush; 
} 

然而,直到我的方法返回,我仍然没有输出。然后我发现我的浏览器正在等待连接关闭,并发现在头文件中设置内容类型可以解决这个问题。

rint $cgi->header(-type => "text/plain; charset=UTF-8", -cookie => $config->{'cookie'}); 

还是没有运气,其实我一直在发送正确的标题。

所以我尽管最好的选择是简单地开始一个新的线程,让我的方法返回。但是当我创建一个新的线程。

use threads ('yield', 
      'stack_size' => 64*4096, 
      'exit' => 'threads_only', 
      'stringify'); 
my $thr = threads->create('doRebuild', $dbconnect, $dbusername, $dbpassword, $bindir); 
sub doRebuild { 
my ($dbconnect, $dbusername, $dbpassword, $bindir) = @_; 
1; 
} 

我得到一个segfault

[周五02月22日10时16分47秒2013] [声明]儿童PID 26076退出信号分割故障(11)

从我读过这个是由mod perl完成的,以确保线程安全运行。不知道这是否正确。

所以我想我会尝试使用{} EXE

{exec 'perl', "$bindir/rebuild_needed_values.pl", qw('$dbconnect' '$dbusername' '$dbpassword');} 

从我收集,这是由国防部的Perl接管过程中,而不是让它返回任何东西。

我知道这不像堆栈溢出问题那样具体,但这种事情必须是一个常见问题,其他人如何解决它?

+2

你试过['fork'](http://perldoc.perl.org/functions/fork.html)吗? – mob 2013-02-21 22:34:56

+0

谢谢暴徒,做到了! – 2013-02-22 00:30:01

您可以使用fork(),但是我喜欢为后台处理推荐http://gearman.org/

像Gearman这样的解决方案要好得多,因为你的后台进程不在Apache的进程链中。

如果使用gearman实现,您的进程将在Apache重新启动后存活。它也更安全,因为Gearman环境可以在chroot监狱中运行。

使用Gearman的一个不错的副作用是您的后台进程可以从其他机器甚至其他语言调用。

Gearman可以让您轻松地从过程中收集数据,并且您可以轻松地将进度信息反馈给您的网络应用程序。