CoroutineBarrier 是用于等待所有引用它的子协程退出的协程同步工具,底层依赖PHP引用计数自动唤醒,无需手动计数或done操作,核心作用是挂起当前协程直至所有子协程执行完毕。

CoroutineBarrier 是用来等所有子协程退出的同步工具
它不是用来传递数据、也不是做信号通知,核心作用就一个:让当前协程挂起,直到所有引用了该 Barrier 对象的子协程全部执行完毕并退出。底层靠 PHP 的引用计数自动触发唤醒,不需要手动调 done() 或 doneAll() 这类方法。
常见错误现象是:Barrier::wait($barrier) 之后程序直接卡住不返回,或者提前返回($count 没加满)。这通常是因为子协程没真正「引用」到屏障对象——比如漏写了 use ($barrier),或用了值传递(use ($barrier) 而非 use (&$barrier)),但注意:PHP 对象默认就是引用传递,所以 use ($barrier) 就够了,不用加 &。
Barrier::make() 和 Barrier::create() 的区别
不同框架/版本里接口名不统一:Barrier::make() 来自 Swoole 官方扩展,Barrier::create() 是 Workerman 5.1+ 提供的兼容接口。两者行为一致,都返回一个可被多个协程共享的屏障对象。不能混用:Swoole 环境下用 make(),Workerman + Swoole 驱动时用 create() 更稳妥。
使用场景取决于你用的是哪个运行时:
- 纯 Swoole 项目 → 用
Barrier::make() - Workerman 5.1+ 且
$worker->eventLoop = Swoole::class→ 推荐Barrier::create() - Hyperf 项目 → 不建议直接用
Barrier,优先走Parallel类封装,它内部已处理好屏障逻辑和超时兜底
Barrier::wait() 的 timeout 参数容易被忽略
Barrier::wait($barrier, $timeout) 第二个参数是毫秒级超时,默认是 -1(无限等待)。线上服务绝不能依赖默认值,否则一个子协程因异常卡死,整个请求就 hang 住。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
建议始终显式设超时,比如:
Barrier::wait($barrier, 3000); // 等最多 3 秒
超时后函数会直接返回,不会抛异常,需自行判断后续逻辑(比如记录日志、降级返回、重试等)。另外注意:超时只影响 wait() 调用方,不影响子协程继续运行——它们仍会在后台执行完再释放引用。
Barrier 和 WaitGroup 的关键差异在哪
最实际的区别是「谁负责计数」:WaitGroup 要你手动 $wg->add() 和 $wg->done();Barrier 完全靠 PHP 引用计数,只要子协程闭包里 use ($barrier),就自动计入,退出即减一。
这意味着:
- Barrier 更轻量,适合简单聚合场景(如并发发 HTTP 请求、批量查 Redis)
- Barrier 无法中途取消某个子任务,也不支持动态增减任务数;WaitGroup 可以在运行中多次
add(),更适合流式任务调度 - Barrier 的析构时机由 GC 控制,极端情况下(如循环引用)可能延迟唤醒;WaitGroup 的
done()是确定性调用,可控性更强
真正要压测或跑长周期任务时,别只看语法简洁——得盯住引用是否真的被释放,最好加日志打点验证 $barrier 析构时间点。

















