当前位置: 首页 > news >正文

浅析std::atomic<T>::compare_exchange_weak和std::atomic<T>::compare_exchange_strong

目录

std::atomic ::compare_exchange_weak 和 std::atomic ::compare_exchange_strong 

核心原理

函数签名

核心区别

典型用法

1. compare_exchange_weak(循环内重试)

2. compare_exchange_strong(单次尝试)

底层机制

总结


std::atomic<T>::compare_exchange_weak 和 std::atomic<T>::compare_exchange_strong 

核心原理

这两个函数都是 原子比较-交换(Compare-and-Swap, CAS) 操作,属于无锁编程的基础操作。其伪代码逻辑如下:

bool compare_exchange(T& expected, T desired) {if (atomic_value == expected) {atomic_value = desired;  // 交换成功return true;} else {expected = atomic_value;  // 更新 expected 为当前值return false;}
}

关键点:整个操作是原子的(不可中断),用于实现无锁数据结构(如队列、栈)。


函数签名

bool compare_exchange_weak(T& expected, T desired, memory_order success = memory_order_seq_cst,memory_order failure = memory_order_seq_cst);bool compare_exchange_strong(T& expected, T desired,memory_order success = memory_order_seq_cst,memory_order failure = memory_order_seq_cst);

  • expected:传入期望值,失败时会被更新为原子变量的当前值。

  • desired:交换成功时设置的目标值。

  • 内存序success(成功时的内存序)和 failure(失败时的内存序)。


核心区别

特性compare_exchange_weakcompare_exchange_strong
虚假失败可能(即使值相等也返回 false不可能(仅在值不相等时失败)
性能更高(某些平台减少重试开销)稍低(保证严格比较)
适用场景循环内重试(如自旋锁)单次尝试或无循环场景
硬件依赖在 ARM/PowerPC 等平台可能虚假失败所有平台行为一致

典型用法

1. compare_exchange_weak(循环内重试)
std::atomic<int> val(10);
int expected = val.load();  // 获取当前值do {int desired = expected * 2;  // 计算新值// 弱版本允许虚假失败,需配合循环
} while (!val.compare_exchange_weak(expected, desired));
  • 适用场景:自旋锁、无锁队列等需反复重试的操作。

2. compare_exchange_strong(单次尝试)
std::atomic<bool> flag(false);
bool expected = false;// 仅尝试一次,强版本保证无虚假失败
if (flag.compare_exchange_strong(expected, true)) {// 成功获取锁
} else {// 已被其他线程修改
}
  • 适用场景:单次检查或无需重试的逻辑。


底层机制

  • 弱版本
    某些硬件(如 ARM)的 CAS 操作可能因缓存一致性协议(如 MESI)或线程调度导致虚假失败,但硬件实现更高效。

  • 强版本
    在弱版本基础上封装循环,直到成功或真实失败:

bool compare_exchange_strong(...) {while (!compare_exchange_weak(...)) {if (atomic_value != expected) break;  // 真实失败退出}
}

总结

场景推荐函数
循环内重试(如自旋锁)compare_exchange_weak
单次尝试或无循环逻辑compare_exchange_strong
需最高性能(低竞争环境)weak + 循环
需代码简洁性strong(避免手动重试)

最佳实践
在循环中优先使用 weak(如实现无锁栈/队列),非循环场景用 strong。例如:

// 无锁栈的 push 操作
void push(Node* new_node) {Node* old_head = head.load();do {new_node->next = old_head;} while (!head.compare_exchange_weak(old_head, new_node));
}

相关文章:

  • Docker 与 Containerd 交互机制简单剖析
  • Apache SeaTunnel Spark引擎执行流程源码分析
  • 刀客doc:阿里巴巴集团品牌部划归集团公关管理
  • 数组题解——​轮转数组【LeetCode】
  • [HTML]iframe显示pdf,隐藏左侧分页
  • 线程池 JMM 内存模型
  • 【题解-Acwing】1022. 宠物小精灵之收服
  • docker镜像中集成act工具
  • 非对称加密实战:Python实现数字签名
  • 【AI论文】扩展大型语言模型(LLM)智能体在测试时的计算量
  • Java+Vue开发的SRM招标采购管理系统,实现招标采购全流程数字化、规范化高效管理
  • MySQL与Excel比较
  • 协议转换赋能光伏制造:DeviceNET转PROFINET网关的通信质检实践
  • 2d-gaussian-splatting:论文分析、全流程环境配置与数据集测试【2025最新版!!!】
  • AntDesignPro动态路由配置全攻略
  • AES算法的Verilog流水线实现(带测试)
  • 【机器人-深度估计】双目深度估计原理解析
  • 汽车制造领域:EtherCAT转Profinet网关案例全面解析
  • Redis精简总结|一主二从哨兵模式(工作机制)|集群模式|缓存的穿透雪崩击穿
  • day040-搭建lnmp服务与数据库迁移