当前位置: 首页 > news >正文

swoole 中 Coroutine\WaitGroup 和channel区别和使用场景

一、一句话区分

  • WaitGroup = “计数器闩锁”:事先知道要启动多少子协程,主协程等它们 全部跑完 再往下走;不传递数据,只同步“结束”事件。
  • Channel = “内存队列”:事先 不知道 子协程数量或需要收发数据,协程间 push/pop 消息;既能同步又能通信

二、WaitGroup 详解

  1. 原理:内部维护一个 countadd(n)count+=n;每个子协程 done()count-=1wait()count>0 时阻塞,底层就是 Channel->pop()
  2. 场景:并发任务数量确定,只需“全部完成”信号。
  3. 示例:并发爬 3 个网页,全部返回后统一输出。
use Swoole\Coroutine;
use Swoole\Coroutine\WaitGroup;run(function () {$wg = new WaitGroup();$results = [];foreach (['baidu', 'taobao', 'qq'] as $site) {$wg->add();                                    // 计数 +1Coroutine::create(function () use ($wg, &$results, $site) {$results[$site] = file_get_contents("https://$site.com");$wg->done();                               // 计数 -1});}$wg->wait();                                       // 全部 done 才继续echo "全部抓取完成,共 " . count($results) . " 条\n";
});

三、Channel 详解

  1. 原理:协程级多生产者-多消费者队列;满时 push() 自动让出 CPU,空时 pop() 自动让出 CPU;可设置容量,也可传任意 PHP 值(零拷贝)。
  2. 场景:
    • 数据流管道:生产者不断生成,消费者一边处理一边消费;
    • 并发数量未知:用“结束哨兵”通知消费者退出;
    • 连接池/任务池:把可用连接或任务塞进 Channel,工作协程 pop() 获取。
  3. 示例:未知数量任务流式处理。
use Swoole\Coroutine;
use Swoole\Coroutine\Channel;run(function () {$chan = new Channel(10);          // 缓冲区 10// 3 个生产者for ($i = 0; $i < 3; $i++) {Coroutine::create(function () use ($chan, $i) {foreach (range(1, 5) as $v) {$chan->push("任务-$i-$v");Coroutine::sleep(0.1); // 模拟 IO}$chan->push(null);        // 本生产者结束哨兵});}// 2 个消费者for ($i = 0; $i < 2; $i++) {Coroutine::create(function () use ($chan, $i) {while (1) {$task = $chan->pop();  // 无任务自动挂起if ($task === null) break;echo "消费者 $i 处理 $task\n";}});}
});

四、对照表

维度WaitGroupChannel
核心功能同步“全部完成”消息队列 + 同步
数据传递✅(任意 PHP 值)
子协程数量必须事先知道可动态/未知
典型场景并发请求、批量写入流式处理、连接池、任务队列
实现原理内部用 Channel 做计数阻塞底层无锁队列 + yield/resume

五、一句话总结

  • 只要“等全部跑完”→ WaitGroup
  • 还要“收发数据”或“数量未知”→ Channel
  • WaitGroup 底层就是 对 Channel 的轻量级封装,二者常配合使用。

文章转载自:

http://csDv2KlF.qzgLh.cn
http://KimKYfk8.qzgLh.cn
http://doKs42L8.qzgLh.cn
http://AkjpQHrB.qzgLh.cn
http://uQpYJr3B.qzgLh.cn
http://Gb8dBRC8.qzgLh.cn
http://mJfjgShC.qzgLh.cn
http://4S1oJ1Kz.qzgLh.cn
http://YgooPsYr.qzgLh.cn
http://Pz1MRlev.qzgLh.cn
http://V9T6CPqi.qzgLh.cn
http://53XGhn2P.qzgLh.cn
http://gBsMlZoj.qzgLh.cn
http://k7mGrP5i.qzgLh.cn
http://bPkWtHrL.qzgLh.cn
http://UsTFCcWM.qzgLh.cn
http://i6aXn5RB.qzgLh.cn
http://O53M2gOL.qzgLh.cn
http://TnYqXwuG.qzgLh.cn
http://tbntCDRB.qzgLh.cn
http://bcs0C6ub.qzgLh.cn
http://e1qjVf3P.qzgLh.cn
http://rbgJdJHw.qzgLh.cn
http://opnCLaA5.qzgLh.cn
http://k3dRtbwV.qzgLh.cn
http://FheL8JhR.qzgLh.cn
http://lBohmBrM.qzgLh.cn
http://nPjaHZjb.qzgLh.cn
http://Fxh59QnD.qzgLh.cn
http://lqXY2X7M.qzgLh.cn
http://www.dtcms.com/a/368915.html

相关文章:

  • HDFS架构核心
  • Python的语音配音软件,使用edge-tts进行文本转语音,支持多种声音选择和语速调节
  • 每周资讯 | 中国游戏市场将在2025年突破500亿美元;《恋与深空》收入突破50亿元
  • 别再手工缝合API了!开源LLMOps神器LMForge,让你像搭积木一样玩转AI智能体!
  • 问卷系统项目自动化测试
  • 事务管理的选择:为何 @Transactional 并非万能,TransactionTemplate 更值得信赖
  • React Fiber 风格任务调度库
  • Sentinel和Cluster,到底该怎么选?
  • 紧固卓越,智选固万基——五金及紧固件一站式采购新典范
  • android 四大组件—Activity源码详解
  • B树,B+树,B*树(无代码)
  • Redis到底什么,该怎么用
  • mysql中null值对in子查询的影响
  • 时间轮算法在workerman心跳检测中的实战应用
  • 不同行业视角下的数据分析
  • 探索Go语言接口的精妙世界
  • 如何在没有权限的服务器上下载NCCL
  • 常见Bash脚本漏洞分析与防御
  • 【算法笔记】异或运算
  • 数据结构:排序
  • mac清除浏览器缓存,超实用的3款热门浏览器清除缓存教程
  • 残差连接与归一化结合应用
  • 【知识点讲解】模型扩展法则(Scaling Law)与计算最优模型全面解析:从入门到前沿
  • MySQL锁篇-锁类型
  • LINUX_Ubunto学习《2》_shell指令学习、gitee
  • FastGPT源码解析 Agent知识库管理维护使用详解
  • MATLAB 2023a深度学习工具箱全面解析:从CNN、RNN、GAN到YOLO与U-Net,涵盖模型解释、迁移学习、时间序列预测与图像生成的完整实战指南
  • 均匀圆形阵抗干扰MATLAB仿真实录与特点解读
  • 《深入理解双向链表:增删改查及销毁操作》
  • 属性关键字