叉后避免空闲页面

时间:2012-08-24 13:02:29

标签: php multithreading apache zend-framework

经过很多努力,我设法让我的php Zend应用程序运行多线程。为此,我已经在CGI模式下配置Apache以使用php pcntl_ *函数。 我有这个问题 这是我的叉子

    function fork() {
    $pid = pcntl_fork();
    if ($pid == -1)
        throw new Exception('fork error on Task object');
    elseif ($pid) {
        # we are in parent class
        $this->pid = $pid;
        # echo "< in parent with pid {$his->pid}\n";
    } else {
        # we are in child
        $sid = posix_setsid();
        if ($sid < 0) {
            exit;
        }
        $this->run();
    }
}

每次调用此函数时,都会创建进程并且运行完美但我在浏览器上失去了对网页的控制权(我无法再浏览我的网站)。它似乎加载页面很长一段时间,直到它给我一个错误。 我需要关闭浏览器(只需一个我无法重新连接的新选项卡),然后重新连接到服务器。 可能是最后创建的进程正在侦听我的http端口吗?我怎么解决这个问题? 感谢

1 个答案:

答案 0 :(得分:0)

对我来说听起来像会话锁定问题 - 无论何时调用session_start(),PHP都会对磁盘上​​的会话文件进行独占锁定,这样两个PHP页面就无法将冲突信息写入同一会话。如果您在锁定到位时拨打session_start(),它将“挂起”,直到锁定会话的过程完成(或致电session_write_close()session_destroy())。

我的猜测是,在你“分叉”你的PHP进程之前,你正在打开一个会话(或者可能采取一些其他的独占锁)并且这个锁没有被正确发布,因为PHP不是设计用于多线程(或者说,多进程)环境。

您可能最好使用systemexec生成一个全新的PHP脚本,并使用消息传递框架将序列化数据传递给它,而不是尝试在PHP下工作。例如ZeroMQ。这样,您不仅可以根据父级设置孩子的初始条件,还可以从子级传递信息

但是,不要忘记以这种方式创建的子进程将在“命令行SAPI”下运行,“命令行SAPI”可能受到不同的php.ini的限制,并且没有定义您通常认为理所当然的事情,如$_SERVER['DOCUMENT_ROOT']