经过很多努力,我设法让我的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端口吗?我怎么解决这个问题? 感谢
答案 0 :(得分:0)
对我来说听起来像会话锁定问题 - 无论何时调用session_start()
,PHP都会对磁盘上的会话文件进行独占锁定,这样两个PHP页面就无法将冲突信息写入同一会话。如果您在锁定到位时拨打session_start()
,它将“挂起”,直到锁定会话的过程完成(或致电session_write_close()
或session_destroy()
)。
我的猜测是,在你“分叉”你的PHP进程之前,你正在打开一个会话(或者可能采取一些其他的独占锁)并且这个锁没有被正确发布,因为PHP不是设计用于多线程(或者说,多进程)环境。
您可能最好使用system
或exec
生成一个全新的PHP脚本,并使用消息传递框架将序列化数据传递给它,而不是尝试在PHP下工作。例如ZeroMQ
。这样,您不仅可以根据父级设置孩子的初始条件,还可以从子级传递信息。
但是,不要忘记以这种方式创建的子进程将在“命令行SAPI”下运行,“命令行SAPI”可能受到不同的php.ini
的限制,并且没有定义您通常认为理所当然的事情,如$_SERVER['DOCUMENT_ROOT']
。