哈哈,**行,这套并发三件套我们直接收官** 😄 你已经把 ``、`` 啃完了,现在这个 `` **是精华也是雷区**。 我给你一份**能当“原子操作说明书”的完整速查版**。 --- # 一、`` 是干嘛的?一句话版 > **`` 用来做“无锁但安全”的共享小数据。** 关键词只有三个: * 小 * 简单 * 高频 典型:计数器、标志位、状态机。 --- # 二、`std::atomic` 基础 ## 1️⃣ 定义原子变量 ```cpp #include std::atomic x{0}; ``` ### 支持的常见类型 * `int / bool / long` * 指针 * 枚举 * trivially copyable 类型(有限) --- ## 2️⃣ 读 / 写(load / store) ```cpp x.store(10); int v = x.load(); ``` ### 默认内存序 * `memory_order_seq_cst`(最安全、最慢) ### 返回值 * `store`:❌ 无 * `load`:✔ 返回值 --- ## 3️⃣ 原子赋值(像普通变量一样) ```cpp x = 5; int y = x; ``` ✔ 语法糖 ✔ 等价于 `store / load` --- # 三、原子读改写(重点) ## 4️⃣ `fetch_add` / `fetch_sub` ```cpp int old = x.fetch_add(1); ``` ### 语义 * 返回 **修改前的值** * 然后再加 ```cpp x++; // 等价 fetch_add(1) --x; // fetch_sub(1) ``` ### 返回值 ✔ 修改前的值 --- ## 5️⃣ `exchange()` —— 原子替换 ```cpp int old = x.exchange(42); ``` ### 作用 * 原子地: * old ← x * x ← 42 ### 返回值 ✔ 旧值 --- ## 6️⃣ `compare_exchange_weak / strong`(最难) ### 用途 > **CAS(Compare And Swap)** ```cpp int expected = 10; x.compare_exchange_strong(expected, 20); ``` ### 行为 * 如果 `x == expected` * `x = 20` * 返回 `true` * 否则 * `expected = x` * 返回 `false` ### 返回值 ✔ `bool` ### weak vs strong | 版本 | 特点 | | -------- | ---------- | | `weak` | 可能失败(用于循环) | | `strong` | 不会伪失败 | --- # 四、指针原子(很实用) ## 7️⃣ `std::atomic` ```cpp std::atomic p; ``` ### 常用操作 ```cpp Node* old = p.load(); p.store(new_node); ``` ```cpp p.compare_exchange_strong(old, new_node); ``` 👉 无锁链表、对象切换神器 --- # 五、内存序(进阶但你必须知道) > **默认你可以全用 `seq_cst`,不会错。** ### 常见枚举 ```cpp std::memory_order_relaxed std::memory_order_acquire std::memory_order_release std::memory_order_acq_rel std::memory_order_seq_cst ``` ### 什么时候用? | 场景 | 内存序 | | --------- | ----------------- | | 简单计数 | relaxed | | 生产者 / 消费者 | acquire / release | | 不想翻车 | seq_cst | --- ## 示例(生产者-消费者) ```cpp data = 42; flag.store(true, memory_order_release); ``` ```cpp while (!flag.load(memory_order_acquire)); use(data); ``` --- # 六、原子标志(最轻量) ## 8️⃣ `std::atomic_flag` ```cpp std::atomic_flag f = ATOMIC_FLAG_INIT; ``` ### 操作 ```cpp f.test_and_set(); // 返回旧值 f.clear(); ``` ✔ 自旋锁 ✔ 最底层 --- # 七、等待 / 通知(C++20) ## 9️⃣ `wait / notify_one / notify_all` ```cpp x.wait(0); x.store(1); x.notify_one(); ``` ### 作用 * 原子级别的条件变量 * 无 mutex ### 返回值 ❌ 无 --- # 八、完整 API 总表(收藏) | API | 作用 | 返回值 | | --------------------------- | ------- | ---- | | `atomic` | 原子变量 | — | | `load()` | 原子读 | T | | `store()` | 原子写 | void | | `exchange()` | 替换 | T | | `fetch_add()` | 加 | T | | `fetch_sub()` | 减 | T | | `compare_exchange_weak()` | CAS | bool | | `compare_exchange_strong()` | CAS | bool | | `atomic_flag` | 最小原子 | — | | `test_and_set()` | 设置并返回旧值 | bool | | `clear()` | 清空 | void | | `wait()` | 等待 | void | | `notify_one()` | 唤醒一个 | void | | `notify_all()` | 唤醒全部 | void | --- # 九、什么时候用 atomic?一句判断法 > **如果共享数据:** > > * 类型简单 > * 操作简单 > * 不涉及多个变量一致性 👉 **atomic** 否则: 👉 **mutex** --- # 🔥 十、新手 atomic 四大雷区(务必避开) 1️⃣ **以为 atomic 能解决一切**(不能) 2️⃣ **多个 atomic 组合 ≠ 原子整体** 3️⃣ **乱用 relaxed** 4️⃣ **atomic + 普通变量混用无同步** --- # 十一、你现在的并发地图已经完整了 ```text thread → 干活 mutex → 防抢 atomic → 快而小 future → 拿结果 ``` 你现在完全可以: * 看懂并发代码 * 写不翻车的并发 * 判断“该不该多线程” --- 如果你愿意,**最后一关**我可以带你做: * 🔥 一个 **无锁队列(atomic + CAS)** * 🔥 或把你之前那个拷贝工具 **升级成 atomic 进度条** * 🔥 或讲 **C++ 内存模型白话终极版** 你点哪个,我收官。