Swoole协程详细学习
1.什么是协程?
协程(Coroutine)是一种用户态的轻量级线程,由应用程序本身管理,而不是由操作系统调度。
轻量级:创建,销毁,切换的成本远低于线程和进程。
非抢占式调度:一个协程不会被系统强行打断,而是主动让出执行权(比如Co::sleep(),yield())。
示例:协程vs线程
如果你使用传统PHP代码(没有swoole),每个数据库查询都会阻塞主线程:
<?php function queryDb(){ sleep(1); return "查询结果"; } $se = explode(' ',microtime()); //返回数组,当前时间微秒数和时间戳秒数 $ntime = $se[0] + $se[1]; echo queryDb(); echo queryDb(); $se1 = explode(' ',microtime());//代码结束计算当前秒数 $etime = $se1[0] + $se1[1]; $htime = $etime - $ntime; //代码执行结束时间 - 代码开始时间 = 执行时间 $hstime = round($htime,3);//获取小数点后三位 var_dump($hstime); //耗时两秒
但在Swoole协程里:
<?php $se = explode(' ',microtime()); //返回数组,当前时间微秒数和时间戳秒数 $ntime = $se[0] + $se[1]; Swoole\Coroutine\run(function(){ go(function(){ Co::sleep(1); echo "查询 1 完成\n"; }); go(function(){ Co::sleep(1); echo "查询 2 完成\n"; }); }); $se1 = explode(' ',microtime());//代码结束计算当前秒数 $etime = $se1[0] + $se1[1]; $htime = $etime - $ntime; //代码执行结束时间 - 代码开始时间 = 执行时间 $hstime = round($htime,3);//获取小数点后三位 var_dump($hstime);
//总耗时约1秒,而不是2秒
协程的好处:即使是单线程,也 可以像异步编程那样同时处理多个任务,提高并发能力。
2.协程vs线程
协程 != 线程,主要区别如下:
| 对比项 | 线程(Thread) | 协程(Coroutine) |
| 创建/销毁 | 需要操作系统管理,开销较大 | 由用户态管理,开销极低 |
| 切换成本 | 线程切换需要CPU调度,涉及上下文切换 | 协程切换仅在用户态,速度极快 |
| 调度方式 | 由操作系统内核调度(抢占式) | 由用户程序调度(非抢占式) |
| CPU利用率 | 可以利用多核CPU并行执行 | 单线程只能运行在一个CPU核心上 |
协程本质上还是运行在单线程里,不会同时利用多个CPU核心,所以它无法真正做到“并行计算”,但它可以高效地处理I/O密集型任务(如数据库查询,网络请求),因为I/O操作会主动让出CPU,其他协程可以继续执行。
3.协程不能利用多核CPU,怎么办?
单个协程只能运行在一个CPU核心上,这意味着无法利用多核CPU,如果要充分利用多核CPU,你需要结合Swoole的多进程模型。
Swoole进程+协程
多进程:每个进程运行在不同的CPU核心上,实现真正的并行计算。
每个进程内部仍然可以用协程来提高I/O性能。
示例:多进程+协程
<?php use Swoole\Process; use Swoole\Coroutine; for($i=0;$i<4;$i++){ $process = new Process(function(){ Coroutine\run(function(){ go(function(){ Co::sleep(1); echo "进程:".posix_getpid()."执行协程任务\n"; }); }); }); $process->start(); };

浙公网安备 33010602011771号