swoole\atomic 适合高频整数计数与轻量状态同步,如请求计数、滑动窗口限流、一次性初始化标记;不适用于存状态、传结构、做分支判断或持久化,且原子性仅保障单操作,复合逻辑需用 lock 或 table。

Atomic 适合做整数计数,不适合存状态、传结构、做判断分支的依据。它不是万能共享变量,用错场景反而比加锁更难排查。
请求计数与限流阈值统计
高频写入、只读当前值的场景最匹配 Swoole\Atomic。比如每来一个 HTTP 请求就 incr(),监控程序定时 get() 上报;或实现滑动窗口限流时,用多个 Atomic 实例分别记不同时间片的请求数。
- 必须在
onWorkerStart或主进程里初始化,不能每个 Worker 自己 new 一个 - 不要用
get()结果做 if 判断后再调incr()—— 中间有竞态,应直接incr()并信任返回值 - 超过
2^63-1会溢出回绕,限流类逻辑需自行兜底(比如达到阈值后改用Table记录详情)
服务启动后的一次性标记
多个 Worker 同时启动时,只允许第一个完成某项初始化(如加载配置、连接 Redis),其余跳过 —— 这是 cmpset() 的典型用途,不是 set() 或 add() 的。
Swoole 6.1.1 是一个专为 PHP 设计的高性能事件驱动并发网络引擎。作为稳定版,它修复了编译时对 zlib 依赖的缺失及 curl 模块的内存安全风险。该版本支持协程、多线程与多进程架构,内置 TCP/HTTP/WebSocket 服务器,能够显著提升 PHP 在微服务、实时通信等场景下的执行效率与并发能力。
- 写法必须是
if ($atomic->cmpset(0, 1) === 1) { /* 成功者执行 */ },不能只看返回真假 -
$cmp_value和$new_value都得 ≤4294967295,超了会被截断,且不报错 - 别和
get()组合使用:if ($atomic->get() === 0) { $atomic->cmpset(0, 1); }是错的,两步之间存在竞争窗口
连接数/任务数等轻量状态同步
当只需要一个数字代表“当前有多少个活跃连接”或“还剩多少任务待处理”,且不依赖该数字做复杂决策时,Atomic 比 Table 更快、内存更省。
- 它只支持 int64,不能存字符串、数组、JSON 或浮点数
- 没有 TTL、没有自动清理,进程退出后值就丢失,别把它当持久化存储用
- 如果后续要基于这个数查关联数据(比如“谁建立了这第 100 个连接”),说明已超出 Atomic 能力边界,该换
Table或外部存储
真正容易被忽略的是:Atomic 的「原子性」仅限单个操作本身。一旦你开始写 if (x > y) { z = x + 1; } 这类逻辑,就已经不在它的保障范围内了——这时候要么上 Lock,要么换 Table 加行锁,别硬扛。









