我很困惑pcntl_fork http://php.net/pcntl_fork in PHP.
我认为它具有多线程功能,但它是如何工作的以及如何在脚本中使用它?
PCNTL 不能创建线程。它仅“分叉”当前的 PHP 进程。这是什么意思?你打电话时pcntl_fork()
,当前进程被分成两个进程。父进程的整个命名空间被复制到子进程中,两个进程继续并行执行,只有一个区别:pcntl_fork()
返回父进程中子进程的 PID0
在孩子。
一些提示:
- 默认情况下它是禁用的。如果您设法启用它,则仅针对 CLI 执行此操作。切勿将其与网络服务器一起使用!它将以非确定性方式表现。它还可能导致整个机器瘫痪。请保持禁用状态并继续阅读。
- 进程之间的通信是可能的,但很糟糕(通过
共享内存中的序列化对象)。
- 文件描述符(和数据库
连接)是共享的,这经常会导致问题。分叉后必须重新连接数据库否则你会得到类似的错误
MySQL server has gone away
当第一个进程关闭连接时,来自所有分叉进程。
- 父进程必须等待子进程完成,否则它将离开僵尸进程
后面的进程消耗系统资源。
这是例子来自文档 http://php.net/manual/en/function.pcntl-fork.php:
<?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 https://www.rabbitmq.com/ and 不错的教程 https://www.sitepoint.com/use-rabbitmq-php/;-) 您还可以尝试有前途的 RabbitMQ 库,名为Bunny https://github.com/jakubkulhan/bunny
PS:使用消息队列而不是分叉给你带来了另一个优势。您可以使用多个服务器处理队列,并随着流量的增长进行水平扩展。
编辑2019-03-07
我玩过很多异步并发框架amphp
在这里我不得不提一下。如果您确实需要在单个请求中运行异步非阻塞任务,我认为amphp
成为今天最好的解决方案。它使用 php 生成器的概念($value = yield $promise
)来执行人类可读的代码,而无需像reactphp那样的承诺地狱。
https://amphp.org/ https://amphp.org/
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)