Swoole 没有所谓的“PHP 层多线程”,Reactor 线程组仅存在于 Master 进程内、由 C++ 管理且不执行 PHP 代码;Worker/TaskWorker 均为单线程进程,真正高并发依赖“多进程 + 协程”组合,而非线程。

直接说结论:Swoole 的「多线程」仅存在于 Master 进程内部的 Reactor 线程组,Worker/TaskWorker 进程本身是多进程、非线程;PHP 层面无法直接操作这些 C++ 线程,也不该试图绕过协程模型去“手写 pthread”。
Reactor 线程组不是 PHP 可见的“多线程”
很多人看到 reactor_thread_count 配置或文档里“Reactor 是多线程”就误以为能在 PHP 里 spawn 线程。实际是:Master 进程启动时,C++ 层用 pthread_create 创建若干 Reactor 线程(默认为 CPU 核数),但这些线程只干三件事:监听 socket、读取网络包、分发请求到 Worker 进程。它们不执行任何 PHP 代码,不加载 Zend VM,也不暴露给 PHP 层。
常见错误现象:
- 在
$server->on('receive')回调里调用new Thread()—— PHP 8+ 已无此类,且 Swoole 不兼容任何用户态线程创建 - 试图用
swoole_process::signal()向 Reactor 线程发信号 —— 信号只被 Master 主线程接收,Reactor 线程屏蔽了大部分信号 - 认为设置
reactor_thread_count = 8就能让一个 HTTP 请求并发处理 8 次 —— 错,单连接始终由同一个 Reactor 线程串行处理
Swoole 6 的 Swoole\Thread 是独立新模块,和 Reactor 无关
2024 年起 Swoole 6 引入实验性 Swoole\Thread 类(需 ZTS 编译的 PHP),但它和底层 Reactor 完全解耦:它只是封装了 POSIX threads,用于 CLI 场景下 CPU 密集型任务(如图像压缩、加密计算),不能用于 I/O 操作,也不能与协程混用。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
使用场景限制很明确:
- 只能在
Swoole\Coroutine\run()外部使用;一旦进入协程环境,Swoole\Thread会直接 fatal - 线程内不能调用任何协程 API(如
Swoole\Coroutine\Http\Client),否则崩溃 - 线程间共享变量需手动加锁(
Swoole\Lock),PHP 的static或全局变量不安全 - 示例中常见的
new Swoole\Thread(function() { usleep(100000); })要配start()和join(),漏掉任一就会丢失执行上下文
真正该关注的并发模型是「协程 + 多进程」组合
生产环境里,99% 的性能瓶颈不在 CPU 计算,而在 I/O 等待(MySQL、Redis、HTTP)。这时候 Reactor 线程再多也没用,关键靠:
- Worker 进程数(
worker_num)控制 CPU 并发上限 - 每个 Worker 内的协程调度器(
Swoole\Coroutine)把阻塞 I/O 变成非阻塞切换 - TaskWorker 进程(
task_worker_num)剥离耗时同步操作(如写文件、发邮件)
参数差异直接影响吞吐:
-
worker_num = 4且未开协程 → 最多同时处理 4 个请求,第 5 个排队 -
worker_num = 4+ 协程 → 单 Worker 可并发数千请求(取决于内存和 fd 限制) -
task_worker_num = 2但task_max_request = 0→ TaskWorker 永不重启,长期运行可能积累内存碎片
最容易被忽略的一点:Reactor 线程和 Worker 进程之间通过共享内存环形缓冲区(swRingBuffer)通信,这个缓冲区大小(package_max_length)设太小会导致大包被截断,设太大又浪费内存——它不随 reactor_thread_count 自动调整,必须手动权衡。

















