当前位置: 首页 > 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));
}
http://www.lqws.cn/news/489097.html

相关文章:

  • 【C++】C++中的虚函数和多态的定义与使用
  • AI 领航设计模式学习:飞算 JavaAI 解锁单例模式实践新路径
  • PROFIBUS DP转ETHERNET/IP在热电项目中的创新应用
  • WinUI3入门9:自制SplitPanel
  • Java基础(三):逻辑运算符详解
  • 提高WordPress网站加载速度和用户体验
  • C# SolidWorks二次开发-实战2,解决SolidWorks2024转step文件名乱码问题
  • 【25】木材表面缺陷数据集(有v5/v8模型)/YOLO木材表面缺陷检测
  • 【开源工具】一键解决使用代理后无法访问浏览器网页问题 - 基于PyQt5的智能代理开关工具开发全攻略
  • 干货分享 如何做好数据可视化?
  • Qt联合Halcon开发四:【详细图解】海康相机配置并链接测试
  • Zynq + FreeRTOS + YAFFS2 + SQLite3 集成指南
  • Windows电脑数据恢复终极指南:从原理到实战
  • el-cascader 设置可以手动输入也可以下拉选择
  • 性能监控与智能诊断系统的全流程
  • (LeetCode 面试经典 150 题) 27.移除元素
  • Java 类加载机制详解
  • Spring AI 项目实战(十二):Spring Boot +AI + DeepSeek + 百度OCR 公司发票智能处理系统的技术实践(附完整源码)
  • C++11 <array>从入门到精通
  • Git新建分支并同步到远程
  • 终端创建虚拟环境
  • Blazor-内置输入组件
  • 华为云 Flexus+DeepSeek 征文|增值税发票智能提取小工具:基于大模型的自动化信息解析实践
  • 2025 年焊接相机十大品牌测评:抗光耐高温解决方案深度解析
  • Three.js入门第一步:两种方式搭建你的3D项目[特殊字符]️
  • CentOS 上安装snmp
  • mac隐藏文件现身快捷键
  • 从 0 到 1 实现 C++ string 类:深入理解动态字符串的底层机制--《Hello C++ Wrold!》(11)--(C/C++)
  • 编程实践:sigmastar330 调用IVE图像处理加速
  • Linux密码校验机制深度剖析:从shadow文件到crypt加密