如何同时运行子进程和父进程

时间:2011-04-25 21:33:19

标签: perl process cgi fork

我有一个网页向cgi脚本发送请求,该脚本基本上必须tar并压缩可能超过50G的大型目录。我正在我的cgi脚本中执行一个进程来执行tarring up任务,同时我在父脚本中向网页发送响应消息。但是,父脚本(即使在没有waitpid($ pid,0)的情况下等待tar进程结束,然后将msg发送到网页,然后通过警告框打印。有没有办法可以立即发送msg,以便用户知道tarring up进程已经启动,并且该进程可以在后台继续。我不想执行exec(),因为我需要在创建此tar时捕获任何错误球。

另外,当我尝试tar这么大的目录时会不会有任何内存问题?

$SIG{CHLD} = 'IGNORE';
$|++;
$pid = fork();
if($pid){ sendResponse($data); exit; }
elsif($pid == 0)
{
    setsid();
    $gpid = fork();
    if(! $gpid)
    {
        qx(tar up big directories over 50G...);
    }
}

1 个答案:

答案 0 :(得分:2)

您对客户端的初始“状态”响应可能会在某处缓冲。如果CGI执行程序设计得当,无缓冲的输出流或刷新流的请求应该导致所有数据包被发送到客户端(他们可能会被接收到的任何内容缓冲,但这超出了您的控制范围)。

有关如何不缓冲初始响应的信息,请参阅Perl常见问题How do I flush/unbuffer an output filehandle? Why must I do this?

请注意,CGI环境也可能调用waitpid()或类似的东西,这就是为什么在子进程存在之后才能看到结果的原因。如果您希望在请求或客户端消失后子进程保持不变,则需要取消子进程与父进程的关联。请参阅perlipc中的Complete Dissociation of Child from Parent

由于您将处理大量数据(50G),这将花费相当长的时间。客户端或服务器很可能在等待tar完成时遇到某种超时。为避免这种情况,您可以确保客户端和服务器都有超时的超时,或者定期在两者之间发送数据以保持连接/请求的活动。您可能需要考虑让tar进程取消关联,并让客户端定期轮询服务器以获得结果。

最后,假设tar没有写入内存缓冲区,它应该具有相对内存效率(假设是现代硬件)。但是,它可能会消耗大量的CPU和I / O.我肯定会对服务的安全性和(无意)拒绝服务的可能性持谨慎态度。