贝利信息

c++中如何使用std::atomic_compare_exchange_c++原子操作CAS用法【详解】

日期:2026-01-23 00:00 / 作者:冰火之心
std::atomic_compare_exchange_weak/strong 是标准定义的底层自由函数,但日常应使用 std::atomic::compare_exchange_weak/strong 成员函数;不存在 std::atomic_compare_exchange_cxx。

直接说结论:std::atomic_compare_exchange_weakstd::atomic_compare_exchange_strong 是 C++ 原子 CAS 的实际入口函数,std::atomic::compare_exchange_weak/strong 成员函数才是日常该用的写法;裸调用自由函数版本几乎没理由 —— 它不自动推导内存序,且容易误传参数类型。

为什么不能直接用 std::atomic_compare_exchange_cxx 这种自由函数?

标准库中根本不存在叫 std::atomic_compare_exchange_cxx 的函数。你搜到的可能是拼写错误、过时资料,或把底层编译器内建函数(如 __atomic_compare_exchange_n)误当成了标准接口。C++ 标准只定义了两个自由函数:

但它们是为泛型算法设计的底层适配器,要求显式传入 std::atomic*、期望值指针、期望值本身、期望更新值、以及两套内存序 —— 容易出错,且和 std::atomic 对象的常规使用习惯脱节。

compare_exchange_weakcompare_exchange_strong 怎么选?

两者语义一致:比较当前值是否等于 expected,是则替换为 desired 并返回 true;否则将当前值写回 expected 并返回 false。关键差异在「失败行为」:

实践建议:

典型用法与易错点

必须注意:第二个参数是引用,且函数会修改它。这是最常踩的坑 —— 忘记取地址或传值导致编译失败或逻辑错误。

std::atomic counter{0};
int expected = 0;
int desired = 1;

// ✅ 正确:expected 是引用,会被更新
if (counter.compare_exchange_strong(expected, desired)) {
    // 成功:counter 从 0 → 1
} else {
    // 失败:expected 已被设为 counter 当前值(比如 1)
    // 此时 expected == 1,可继续用它重试
}

// ❌ 错误:传值,expected 不会被更新,下次 compare_exchange 还拿旧值比
// int expected = 0;
// counter.compare_exchange_strong(expected, desired); // 编译不过(类型不匹配)

// ❌ 错误:取地址但没声明为引用,导致修改的是临时量
// counter.compare_exchange_strong(&expected, desired); // 编译不过(参数类型不对)

其他要点:

CAS 看似简单,但 expected 的生命周期、内存序搭配、weak/strong 的循环结构,三者稍有错位就会导致死循环、ABA 问题或数据竞争 —— 尤其在多核弱一致性架构上,别只盯着函数名,得盯住变量怎么传、谁改了它、改完之后你还信不信它。