std::atomic::compare_exchange_strong 是实现多线程同步的关键工具,用于自旋锁、无锁队列出队、双重检查锁定和带版本号的乐观锁更新,确保状态变更的原子性与条件严格性。

如果您在实现多线程同步逻辑时需要确保某次状态变更仅在特定条件下发生,且必须严格区分“值已变更”与“纯操作失败”,则 std::atomic::compare_exchange_strong 是关键工具。以下是针对该函数在并发锁场景中的具体应用步骤:
一、基于 compare_exchange_strong 的自旋锁实现
该方法利用 CAS 的强语义构建无锁自旋等待机制,确保仅当锁标志处于未占用状态(如 false)时才成功获取,且不会因架构级虚假失败而误判。
1、声明原子布尔标志:std::atomic
2、定义 acquire 函数,使用 do-while 循环配合 compare_exchange_strong:bool acquired = false; while (!acquired) { bool expected = false; acquired = lock_flag.compare_exchange_strong(expected, true, std::memory_order_acquire, std::memory_order_relaxed); }
3、在临界区执行受保护操作。
4、释放锁:lock_flag.store(false, std::memory_order_release);
二、无锁队列出队操作中的精确状态判定
在实现单生产者单消费者无锁队列时,出队需严格识别头节点是否已被其他线程修改;compare_exchange_strong 可避免 weak 版本在 ARM 平台上因 LL/SC 限制导致的非预期失败,从而保障出队原子性与逻辑正确性。
1、读取当前 head 指针:Node* old_head = head.load(std::memory_order_acquire);
2、计算新 head:Node* next = old_head->next;
3、执行强一致性 CAS:if (head.compare_exchange_strong(old_head, next, std::memory_order_acq_rel, std::memory_order_acquire)) { 此时可确认 old_head 未被其他线程抢先修改,出队操作成立 }
4、若返回 false,则 old_head 被更新,需重新读取并重试。
三、双重检查锁定模式(DCLP)中的初始化保护
在延迟初始化全局资源时,compare_exchange_strong 用于确保仅首个线程执行构造,其余线程直接读取已初始化实例,避免竞态导致的重复构造或未定义行为。
1、声明原子指针:std::atomic
2、首次调用时,以 nullptr 为 expected 尝试交换:Resource* expected = nullptr; Resource* desired = new Resource(); if (instance.compare_exchange_strong(expected, desired, std::memory_order_release, std::memory_order_relaxed)) { 初始化成功,当前线程负责构造 } else { delete desired; }
3、后续调用直接 load:return instance.load(std::memory_order_acquire);
四、带版本号的乐观锁更新
当共享结构体需支持多字段协同更新时,可将版本号嵌入原子整型,通过 compare_exchange_strong 实现“读-校验-写”三步原子化,防止 ABA 问题引发的状态覆盖。
1、定义原子版本号:std::atomic
2、读取当前版本:uint64_t expected_ver = version.load(std::memory_order_acquire);
3、修改业务数据后,尝试提交:uint64_t desired_ver = expected_ver + 1; if (version.compare_exchange_strong(expected_ver, desired_ver, std::memory_order_acq_rel, std::memory_order_acquire)) { 说明期间无其他线程提交,本次更新有效 }
4、若失败,说明版本已变,需重新读取数据与版本号后重试。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











