在FastCGI中fork()的正确方法是什么?

时间:2010-04-07 11:57:39

标签: perl ipc fork fastcgi

我在Catalyst + FastCGI下运行了一个应用程序。我希望fork()能够在后台做一些工作 我很久以前就把这个代码用于普通的CGI(并且它有效):

defined(my $pid = fork) or die "Can't fork: $!";
if ($pid) {
    # produce some response         
    exit 0;
}

die "Can't start a new session: $!" if setsid == -1;
close STDIN  or die $!;
close STDOUT or die $!;
close STDERR or die $!;
# do some work in background

我在FastCGI下尝试了一些变化,但没有成功。如何在FastCGI下进行分叉?

更新:这就是我现在所拥有的:

defined(my $pid = fork) or die "Can't fork: $!";
    if ($pid) {
        $c->stash->{message} = 'ok';
        $c->detach($c->view('JSON'));
    }
    die "Can't start a new session: $!" if setsid == -1;
    close STDIN  or die $!;
    close STDOUT or die $!;
    close STDERR or die $!;
    # do some work, then exit() 

我使用AJAX调用发送请求,并在firebug控制台中出现“502 Bad Gateway”错误。

2 个答案:

答案 0 :(得分:3)

我认为此常见问题解答有正确的答案: http://www.fastcgi.com/docs/faq.html#Perlfork

你应该在fork之前做$request->Detach();,在fork for code of code之后做$request->Attach();,其中$ request是当前的FCGI对象。至少,它对我有用。

对于Catalyst :: Engine :: FastCGI,您可能需要修补Catalyst :: Engine :: FastCGI才能访问$request变量,因为它是run()方法的本地变量(在当前使用CPAN的版本中。

答案 1 :(得分:2)

这部分不适用于FastCGI:

if ($pid) {
    # print response         
    exit 0;
}

您将在父进程中退出,因此它将停止响应FastCGI请求。

setsid()和close()用于守护你的后台进程。在您的情况下,这可能是必要的,也可能不是。