php在后台启动进程并等待它完成

时间:2013-08-26 08:57:39

标签: php

我有两个用户可以调用的脚本(A& B)。

如果用户调用A,我会进行一堆数据库访问并检索结果以返回给用户。在我找到了我需要发回的内容之后,然后我做了一堆额外的处理和修改数据库。

我想知道是否可以将结果返回给用户,然后在某种后台任务中执行剩余的处理。

另一个条件是,如果调用脚本A的用户然后调用脚本B,则用户通过调用A触发的任何处理任务必须完成,否则脚本B必须等到它完成。

有办法做到这一点吗?

4 个答案:

答案 0 :(得分:1)

Php在关闭请求后无法执行任务,因为当php进程完成时,请求(以及发送给浏览器的响应)确实已关闭。

另外,php适用于短操作,不会像守护程序一样长时间运行,因为php缺少一个好的垃圾收集器(所以它会在崩溃之前吃掉所有可用的内存)。

您正在寻找的是一个队列。当您需要执行某些资源(或时间)密集型任务时,可以将任务放入队列中。然后,工作进程将从队列中获取一个项目,然后执行该任务。

这使您可以通过限制工作人员数量来限制资源使用,以避免峰值和服务失败。

看看resque(用于自托管解决方案)或iron.io(用于云,免费安装解决方案)

如果您在共享主机上(因此,没有队列且没有可用的cron),那么我建议您查看iron.io推送队列。当队列不为空时,那种队列将调用您的服务器(通过HTTP)向其发送任务。这样,所有轮询/检查队列都在iron.io端完成,您只需设置一个执行任务的常规页面。

此外,如果您希望脚本B等待脚本A完成,则必须创建某种锁定系统。但是我会尽量避免这种情况,如果我是你,因为这会导致死锁(一个线程在等待另一个线程,但另一个线程永远不会完成从而永远阻塞等待线程)

答案 1 :(得分:0)

你可以这样做:

a.php只会

<?php

echo "hi there!";

//in order to run another program in background you have to
//redirect std e err output and use &
//otherwise php will wait for the output
$cmd = "/usr/bin/php ".__DIR__."/b.php";
`$cmd > /dev/null 2> /dev/null &`;

echo "<br>";

echo "finished!";

b.php

<?php

$f = fopen(__DIR__."/c.txt", "w");

//some long running task
for($i=0; $i<300; $i++){
        fwrite($f, "$i\n");
        sleep(1);
}
fclose($f);

注意:

  • 不是最优雅的解决方案,但它可以胜任。
  • 如果您只想运行一个b.php,可以添加一个pid检查。
  • 该过程将与http用户(apache或其他)一起运行,确保它具有适当的权限。

答案 2 :(得分:-1)

我猜您正在寻找Ignore_user_abort()。 当浏览器关闭连接时,此函数可使脚本保持活动状态以进行清理任务。

http://php.net/manual/en/function.ignore-user-abort.php

您可以通过header()set_time_limit()ignore_user_abort()connection_status()的良好组合来虚拟地解决浏览器请求。

与Ajax结合使用非常有趣。

答案 3 :(得分:-1)

做这样的事情最好使用nodejs,PHP是同步的并且逐行完成它的工作。(你也可以通过{{1}开发异步代码,如python。 lib)。

但是对于你的问题,你应该开发类似的东西:

asyncore

看看ob_flush() php函数,这不会等到结束进程,然后为用户渲染html。