我对pcntl_fork
PHP 感到困惑。
我认为它执行多线程,但它是如何工作的,我将如何在脚本中使用它?
PCNTL 不能制作线程。它只“分叉”当前的 PHP 进程。这是什么意思?当您调用 时pcntl_fork()
,当前进程分为两个进程。父进程的整个命名空间被复制到子进程中,两个进程继续并行执行,只有一个区别:pcntl_fork()
在父进程和子进程中返回子进程的 PID 0
。
一些提示:
MySQL server has gone away
否则当所有分叉进程中的第一个关闭连接时,您将收到类似所有分叉进程的错误。这是文档中的示例:
<?php
$pid = pcntl_fork();
if ($pid == -1) {
die('could not fork');
} else if ($pid) {
// we are the parent
pcntl_wait($status); //Protect against Zombie children
} else {
// we are the child
}
但请记住,PHP 只是脚本语言。它不是为并行计算而设计的。根据您的需要,您可以更好地同时运行 CRON、消息队列或低级语言的程序。
分叉的 PHP 程序很难阅读、理解和调试。维护该程序将是一场噩梦。
不要犯错,避免分叉。你不需要它。你真正需要的是异步任务运行器。好消息,有RabbitMQ和不错的教程;-) 您也可以尝试有前途的 RabbitMQ 库,称为Bunny
PS:使用消息队列而不是分叉为您提供了更多优势。您可以使用多台服务器处理队列,并随着流量的增长水平扩展。
编辑 2019-03-07
我玩过很多异步并发框架amphp
,这里不得不提一下。如果您确实需要在单个请求中运行异步非阻塞任务,我认为amphp
这是当今最好的解决方案。它使用 php 生成器 ( $value = yield $promise
) 的概念来执行人类可读的代码,而无需类似 reactphp 的承诺地狱。