3、多进程
PHP是单进程执行的,在处理高并发时主要依赖于Web服务器或PHP-FPM的多进程管理以及进程的复用,但在PHP实现多进程尤其是后台PHP-CLI模式下处理大量数据或运行后台Deamon守护进程时,多进程的优势自然是最好的。
PHP的多线程也曾被人提及,但进程内多线程资源共享和分配问题难以解决,PHP有一个多线程过的扩展pthreads,它要求PHP环境必须是线程安全的。
多进程简单来说就是多个进程同时执行多个任务,可以将耗时但又必须执行的查询分成多个子进程进行操作。
PHP多进程不支持PHP-FPM和CGI模式,只能通过PHP-CLI模式。
PHP多进程适用于定时任务执行,互斥且耗时的任务。
开发使用PHP多进程的场景也就是使用PHP-FPM,PHP-FPM作为PHP的多进程管理器,当使用Nginx作为WebServer时,来自客户端的请求会根据Nginx的路由配置,将以PHP为后缀的文件转发给PHP-FPM。当多个用户同时请求API时,PHP-FPM会开启多个PHP的处理进程进行处理。
检查原生PHP是否支持多进程扩展,可以通过查看是否安装了pcntl:
php -m | grep pcntl
多进程的优势
PHP相比C、C++、Java少了多线程,PHP中只有多进程的方案,所以PHP中的全局变量和对象不是共享的,数据结构也不能跨进程操作,另外Socket文件描述符也不能共享…
多线程看似比多进程强大的多,多线程的缺陷也同样明显:
数据同步时,要么牺牲性能到处加锁,要么使用地狱难度的无锁并发编程。
当程序逻辑复杂后,锁会越来越难以控制。一旦死锁,程序基本上就完了。
某个线程挂掉后所有的线程都会退出
相比较多线程,多进程拥有的优势是:
配合进程间通信,基本可以实现任意数据共享。
多进程不需要锁
多进程可以共享内存的数据结构实现一些多线程的功能
对于并发服务器核心是IO,并非大规模密集运算,高并发的服务器单机能维持10W连接,每秒可以处理3~5W笔消息收发。
普通的Web应用都是IO密集型的程序,瓶颈在MySQL上,所以体现不出PHP的性能优势。但在密集计算方面比C/C++、Java等静态编译语言相差几十倍甚至上百倍。
例如:使用Swoole多进程方式同时访问Web地址,multi.php:
<?php
echo "process begin: ".date("Y-m-d H:i:s").PHP_EOL;
//初始化地址数组
$urls = [
"http://www.baidu.com",
"http://www.360.com",
"http://www.qq.com",
"http://www.sina.com"
];
//初始化数组用于回收线程管道内容
$workers = [];
//按照任务分配线程
for($i=0; $i<count($urls); $i++){
$url = $urls[$i];
//创建进程
$process = new swoole_process(function(swoole_process $worker) use($url){
//模拟执行耗时任务
file_get_contents($url);
//sleep(1);//模拟耗时1秒
echo $url.PHP_EOL;
}, true);
//开启进程
$pid = $process->start();
$workers[$pid] = $process;
}
//打印管道内容
foreach($workers as $worker){
echo "pid : ".$worker->read();
}
echo "process end: ".date("Y-m-d H:i:s").PHP_EOL;
运行代码:
- php multi.php
得到输出:
process begin: 2020-05-12 16:19:48
pid : http://www.baidu.com
pid : http://www.360.com
pid : http://www.qq.com
pid : http://www.sina.com
process end: 2020-05-12 16:19:49