我对PHP中的pcntl_fork
感到困惑。
我认为它确实是多线程的,但它是如何工作的以及如何在脚本中使用它?
答案 0 :(得分:40)
PCNTL无法创建线程。它只是“分叉”当前的PHP进程。这是什么意思?当您致电pcntl_fork()
时,当前流程将分为两个流程。父进程的整个命名空间被复制到子进程中,并且两个进程继续并行执行,只有一个区别:pcntl_fork()
返回父级的子级PID和子级的0
。
一些提示:
MySQL server has gone away
等错误。以下为示例from documentation:
<?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,消息队列或低级语言程序,从而做得更好。
Forked PHP程序很难阅读,理解和调试。维持该计划将是一场噩梦。
不要犯错误并避免分叉。你不需要它。你真正需要的是异步任务运行器。好消息,有RabbitMQ和nice tutorial ;-)你也可以尝试一下名为Bunny的有希望的RabbitMQ库
PS:使用消息队列而不是分叉为您提供了另一个优势。您可以使用多个服务器处理队列,并在流量增长时水平扩展。
编辑2019-03-07
我使用异步并发框架amphp
玩了很多,我必须在这里提一下。如果您确实需要在单个请求中运行异步非阻塞任务,我认为amphp
是今天最好的解决方案。它使用php生成器($value = yield $promise
)的概念来执行人类可读的代码而没有像reactphp一样的承诺地狱。