swoole v6.0 多线程支持需同时满足:php 为 zts 模式(php -i | grep "thread safety" 输出 enabled)、编译 swoole 时启用 --enable-swoole-thread、且禁用 pthreads 扩展;否则 swoole\thread 类不可用。

直接说结论:Swoole v6.0 的多线程支持不是“协程 + 线程”二选一,而是必须明确启用 --enable-swoole-thread 编译选项、且 PHP 必须是 ZTS(Zend Thread Safety)模式,否则 Swoole\Thread 类根本不可用,运行时会报 Class 'Swoole\Thread' not found。
编译前不确认 ZTS 模式,Swoole\Thread 一定加载失败
很多人本地装了 Swoole 6,写 new Swoole\Thread() 却提示类不存在,第一反应是版本不对。其实更大概率是 PHP 本身没开 ZTS —— 这个开关在编译 PHP 时就决定了,运行时无法开启。
- 检查方式:
php -i | grep "Thread Safety",输出enabled才合格;若为disabled,必须重装 ZTS 版 PHP(如 Ubuntu 下用apt install php-zts,或源码编译加--enable-maintainer-zts) - PECL 安装的 swoole 默认不带线程支持,必须用源码编译:
./configure --enable-swoole-thread --enable-iouring - 即使编译成功,
php.ini中也要确认extension=swoole.so已启用,且无其他扩展冲突(如某些旧版 xdebug 会干扰 ZTS)
Swoole\Thread\Map 和 Swoole\Table 的适用边界很清晰
新手常把二者混用,结果在多线程场景下出现数据覆盖或崩溃。核心区别在于:前者是线程安全容器,后者是进程间共享内存,但默认不线程安全。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
-
Swoole\Thread\Map:每个线程独享一份底层哈希表,适合存线程私有上下文(如当前请求的 trace_id、用户 token),无需锁,但不能跨线程读写 -
Swoole\Table:所有 Worker 进程共享同一块内存,适合全局计数(如总连接数)、配置广播,但set()/get()不原子,多线程写同一行必须显式$table->lock($key) - 误用典型:
Swoole\Table存 session 数据 → 多个线程并发set()同一个user:123键 → 最后只保留最后一次写入,中间更新丢失
iouring 支持不是“开个开关就行”,依赖系统和内核版本
--enable-iouring 编译成功 ≠ 文件操作自动走 iouring。它对运行环境有硬性要求,否则会静默回退到传统 syscall,性能毫无提升。
- 必须满足:
Linux kernel >= 5.1+liburing >= 2.0(Ubuntu 22.04+ / CentOS Stream 9+ 较稳妥) - 验证是否生效:
strace -e trace=io_uring_enter,io_uring_setup php your_script.php,能看到系统调用才真正启用 - 注意函数范围:只有
file_get_contents、fopen、mkdir、unlink等少数函数被 hook,file_put_contents('php://stdout')这类伪协议不走 iouring - 常见坑:Docker 容器未挂载
/dev/urandom或禁用io_uringcapability,导致初始化失败,日志里只打印WARNING: iouring is not available
真正容易被忽略的是:Swoole 6 的多线程能力与协程调度器目前仍不兼容嵌套使用。比如在线程中调用 Co\run(),会导致协程调度器状态错乱,极大概率 crash。线程内需做异步 IO,应改用 Swoole\Coroutine::create() 显式创建协程,而非复用主线程的 Runtime 上下文。










