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

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://www.xdnf.cn/news/20060.html

相关文章:

  • 问卷系统项目自动化测试
  • OpenCV: cv::warpAffine()逆仿射变换详解
  • 模型剪枝----ResNet18剪枝实战
  • Linux之Ubuntu桌面化操作系统的安装
  • AI生成内容的版权问题解析与实操指南
  • Sunlord破解AI服务器供电难题!揭秘高效、小型化电感黑科技
  • MQTT 认证与授权机制实践(二)
  • 盲盒抽卡机小程序功能版块设计的合理性评估维度
  • ZooKeeper vs Redis:分布式锁的实现与选型指南
  • Vulkan进阶系列11 - RenderPass 设置对渲染性能的影响
  • 批量生成角色及动画-角色动画转化为mixamo骨骼(二)
  • 深入浅出 全面剖析消息队列(Kafka,RabbitMQ,RocketMQ 等)
  • 分类、目标检测、实例分割的评估指标
  • 数据结构基础之队列:数组/链表
  • 【C++】 list 容器模拟实现解析
  • 富文本编辑器:主流插件简介与wangEditor深度配置指南
  • 【c++】c++输入和输出的简单介绍
  • Mac M4环境下基于VMware Fusion虚拟机安装Ubuntu24.04 LTS ARM版
  • 在 CentOS 9 上安装 Docker 的完整指南
  • 蚂蚁 S21 XP+ HYD 500T矿机评测:SHA-256算法与高效冷却技术的结合
  • 数字隔离器,新能源汽车PTC中的“电气安全卫士”
  • git命令解析
  • 家庭网络异常降速问题排查处理方案
  • 查找算法 -- 二分查找 O(log n)
  • 前端笔记2025
  • 快速了解迁移学习
  • Jupyter Notebook的交互式开发环境方便py开发
  • 一文看懂什么是GaN HEMT以及其工艺流程(氮化镓高电子迁移率晶体管)
  • 数据结构之双向链表
  • Nginx 配置详解与虚拟主机实战指南