比较并交换:CAS 模式
使用 compare_exchange_weak 和 compare_exchange_strong 实现无锁更新
比较并交换:CAS 模式 是 CoddyKit 上的免费 C++ Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 C++ Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 C++ Academy 课程共包含 4 节课。
CAS 原语
比较并交换会以原子方式读取、比较并有条件地写入。它是大多数无锁算法的基础。
C++ 比较交换
std::atomic 中有两种变体:
compare_exchange_strong(expected, desired)— 当前值等于 expected 时成功compare_exchange_weak(expected, desired)— 可能发生虚假失败
CAS 循环的构成
经典的 CAS 循环:读取、计算、尝试写入。如果另一个线程赢得竞争,则重试。
std::atomic<int> a{0};
int old = a.load();
int next;
do {
next = compute_new(old);
} while (!a.compare_exchange_weak(old, next));使用 CAS 进行原子更新
当新值取决于旧值时使用 CAS。直接使用 store 会丢失并发线程进行的更新。
// Atomic max
int current = a.load();
while (newval > current && !a.compare_exchange_weak(current, newval));无锁栈:push
简单的无锁栈 push 操作使用 CAS,将一个新节点安装到栈顶。
struct Node { int value; Node* next; };
std::atomic<Node*> head{nullptr};
void push(int v) {
Node* n = new Node{v, nullptr};
n->next = head.load();
while (!head.compare_exchange_weak(n->next, n));
}虚假失败
即使值相等,compare_exchange_weak 也可能失败——在 ARM 等平台上,底层指令允许这样做。在循环中使用它;当重试成本很高时,使用 strong。
更新模式:重置
仅当值尚未改变时,将其重置为已知状态。
int expected = 42;
if (a.compare_exchange_strong(expected, 0)) {
// a was 42 and is now 0
}构建块:原子计数器
对于普通计数器,fetch_add 比 CAS 循环更简单、更快。
构建块:原子标志
对于简单的布尔标志,std::atomic_flag 比 std::atomic<bool> 更轻量,并支持 test_and_set。
推理并发行为
无锁代码出了名地难以推理。请进行严格测试(TSan、模糊测试),在可用时使用形式化模型,并优先采用经过充分实战检验的现有实现。
何时选择 CAS
在以下情况下使用 CAS:
- 多个线程频繁更新同一个值
- 互斥锁竞争成为性能瓶颈
- 临界区非常短且简单
何时不应使用 CAS
在以下情况下避免使用 CAS:
- 更新需要执行两三个以上的操作
- 正确性比吞吐量更重要
- 团队缺乏无锁编程方面的专业知识
快速检查
为什么我们通常在循环中使用 compare_exchange_weak?
回顾
只有当值等于预期值时,比较并交换才会以原子方式更新该值。CAS 循环无需加锁即可处理并发更新。在循环中使用 compare_exchange_weak,进行一次性尝试时使用 strong。
常见问题解答
「比较并交换:CAS 模式」课时是免费的吗?
是的 — 「比较并交换:CAS 模式」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 C++ Academy 课程的其余内容,请升级到 CoddyKit PRO。 C++ Academy 课程共包含 4 节课。
「比较并交换:CAS 模式」这节课中我会学到什么?
使用 compare_exchange_weak 和 compare_exchange_strong 实现无锁更新 你通过在浏览器中直接运行的动手代码来练习 C++ Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。
学习 C++ Academy 需要有经验吗?
无需任何先前经验。CoddyKit 上的 C++ Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。
「比较并交换:CAS 模式」课时需要多长时间?
大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。
我能在这节 C++ Academy 课中编写并运行代码吗?
能。每节 C++ Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。
此课程中的所有课时
- std::atomic 与内存顺序
- 比较并交换:CAS 模式
- 无锁队列实现
- 危险指针与 ABA 问题