0Pricing
C++ Academy · 课时

比较并交换: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 反馈 — 无需本地设置。

此课程中的所有课时

  1. std::atomic 与内存顺序
  2. 比较并交换:CAS 模式
  3. 无锁队列实现
  4. 危险指针与 ABA 问题
← 返回 C++ Academy