enable_coroutine控制回调是否默认运行于协程上下文:开启时onrequest等自动在协程中执行,可直用co::sleep等api;关闭时退至同步模式,co::sleep会报错,file_get_contents等仍阻塞,且task_enable_coroutine失效。

enable_coroutine 控制的是整个 Swoole Server 的协程执行环境是否默认启用——它不是“开个协程功能”,而是决定你的 onRequest、onReceive 等回调是否天然运行在协程上下文中。
enable_coroutine=true 时,onRequest 自动进入协程
你不需要写 go(),co::sleep()、Swoole\Coroutine\MySQL、Swoole\Coroutine\Http\Client 就能直接用。底层已为你启动一个协程,所有 I/O 操作(只要被 hook)都自动非阻塞。
- HTTP 请求之间变量隔离,不会互相污染
-
Co::getcid()可查当前协程 ID,便于日志追踪 - 定时器
after/tick也跑在协程里,支持co::sleep() - 错误堆栈会带上协程上下文,比纯同步模式更易定位
enable_coroutine=false 时,回调退回到纯同步模式
这不是“协程被禁用了”,而是根本没进协程调度器——co::sleep() 会直接报错:Fatal error: Uncaught Swoole\Error: must be called in the coroutine。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
-
go()仍可用,但必须手动包裹所有异步逻辑,否则并发不生效 -
file_get_contents()、curl_exec()、sleep()全部同步阻塞,卡死整个 worker 进程 - 行为与 Swoole 1.x 完全一致,适合迁移过渡或排查协程问题
task_enable_coroutine 依赖 enable_coroutine 才生效
很多人配了 'task_enable_coroutine' => true 却发现 onTask 里用不了 co::sleep(),原因就是 enable_coroutine 是 false ——这个配置根本不会被读取,Swoole 直接降级为同步执行。
- 正确组合只有两种:
enable_coroutine=true(推荐),或两者都false -
task_enable_coroutine的本质是“在已有协程环境里,为每个任务再启一个子协程”,不是独立入口 - 即使开了
enable_coroutine,若没调用Swoole\Runtime::enableCoroutine(SWOOLE_HOOK_ALL),file_get_contents()等仍会阻塞
协程真正不阻塞,靠的是 Runtime Hook,不是 enable_coroutine
enable_coroutine 只解决“有没有协程上下文”,而 file_get_contents()、curl_exec()、sleep() 是否真的协程化,取决于 Swoole\Runtime::enableCoroutine() 的 flag 设置。
- 默认只 hook 基础 socket 相关调用,
SWOOLE_HOOK_ALL才覆盖全部常见系统调用 - 压测数据显示:
SWOOLE_HOOK_ALL比仅 hook stdio 的 QPS 高 4 倍以上,P99 延迟低 10 倍 - 必须放在
$server->start()之前调用,且不能重复启用
最容易被忽略的点:开了 enable_coroutine ≠ 所有函数都自动协程化。没配 Runtime::enableCoroutine(),或者只配了部分 flag,curl_exec() 依然会拖垮整个 worker。










