协程容器是swoole协程运行的必要前提,http服务器、process启动时自动创建,裸写脚本需显式调用co\run();未进容器时go()等退化为同步阻塞,进容器后io或co::sleep()触发挂起与调度实现并发。

协程容器是 Swoole 协程运行的必要前提,没有它,go()、Co::sleep()、协程客户端(如 Co\MySQL)等行为都会退化为同步阻塞执行,甚至直接报错或无效果。
协程容器决定协程能否真正并发
在容器外调用 go(),协程会立即启动但串行执行;放进 Co\run() 容器后,遇到 IO(如 $mysql->query())或 Co::sleep() 时才会挂起并让出 CPU,其他协程才能被调度 —— 这才是协程“并发”的本质。
- 不进容器:两个
go()调用,第二个要等第一个sleep(2)结束才开始,输出顺序固定 - 进容器:
sleep(1)的协程先结束,sleep(2)的后输出,体现调度能力 - HTTP 服务器、
Process启动时自动创建容器,但裸写脚本(比如 CLI 测试)必须显式调用Co\run()
哪些地方默认有协程容器?
不是所有 Swoole 回调都自动带容器。只有明确文档标注“协程环境”或启用 enable_coroutine 的场景才安全:
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
-
Swoole\Http\Server+enable_coroutine => true(默认开启)→onRequest回调内可用协程 -
Swoole\Process或Swoole\Process\Pool构造时传['enable_coroutine' => true]→ 子进程内自动初始化容器 -
Swoole\Server(TCP/UDP)默认不启用,需手动设置enable_coroutine,否则go()无效 - CLI 直接跑
php test.php:零容器,必须包一层Co\run(...)
Co\run() 不能嵌套,也别滥用
Co\run() 是协程程序的入口,类似 main(),重复调用会触发致命错误 Fatal error: Uncaught RuntimeException: Co\run() can not be nested。
- 常见误用:在已处于协程容器的回调里(如
onRequest)又写一遍Co\run() - 替代方案:想在已有协程中再启调度逻辑,直接用
go(),而不是再套容器 - 注意副作用:容器内代码之后的普通 PHP 语句(比如
echo "done";)不会执行 —— 容器会阻塞直到所有子协程退出
真正容易被忽略的是:协程容器不是“魔法开关”,它只提供调度上下文;协程是否并发,最终取决于你是否用了真正支持协程的 API(如 Co\MySQL 而非原生 mysqli),以及这些 API 是否在容器内被调用。










