-1

经过真正的努力,我设法让我的 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 端口?我该如何解决这个问题?谢谢

4

1 回答 1

0

对我来说,这听起来像是一个会话锁定问题 - 每当您调用 时session_start(),PHP 都会对磁盘上​​的会话文件进行排他锁定,因此两个 PHP 页面无法将冲突信息写入同一个会话。如果您session_start()在该锁到位时调用,它将“挂起”,直到锁定会话的进程完成(或调用session_write_close()or session_destroy())。

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

与其试图让真正的 fork 在 PHP 下工作,不如使用systemor生成一个全新的 PHP 脚本exec,并使用诸如ZeroMQ. 这样,您不仅可以根据父级设置子级的初始条件,而且实际上可以从子级传回信息

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

于 2012-08-24T13:22:36.877 回答