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

跟我学C++中级篇—标准库中的CAS接口分析

一、从无锁编程谈起

在前面的多线程编程时,提到过CAS这种无锁编程的情况。无锁编程的一个重要的前提是标准库中(其实系统底层也提供了类似的机制)的原子操作类型,它也是硬件基础的比较交换指令的向上延伸。而要想实现CAS,C++标准库中提供了两个接口函数,即compare_exchange_strong和 compare_exchange_weak。
也就是说,在不同的平台或不同的语言中,CAS的接口和实现机制是略有不同,这一点大家要明白。

二、强弱比较交换

compare_exchange_strong和 compare_exchange_weak,很好理解,从字面上讲,强比较交换是严格的比较,不会出现伪失败(spurious failure),性能稍差一些;而弱比较交换则相对宽容一些,有可能出现伪失败,但性能稍微强一些。从设计角度来看,这也非常必要的。不同的情况要有不同的方法来匹配而不能以一敌千,生拉硬配。二者的区别在于,强比较交换只有在比较真正不同的情况下才会失败,而弱比较交换则有可能在比较相同的情况也会失败。
先看一下在C++中的定义:

boolcompare_exchange_weak(T&expected,T desired,std::memory_order success,std::memory_order failure);

这里有一个比较让英文一般人费解的地方,先看一下这个函数的意义:

  1. 比较当前的原子变量值是否等于预期值(由调用者提供)。
  2. 如果相等,则将原子变量的值设置为一个新的值(由调用者提供)。
  3. 如果不相等,则将当前的原子变量值写入预期值,并返回 false。
    这里面有一个预期值,可在上面的参数中,expected和desired都是期望的意思,那上面的说法是不是有点让人费解,这两个变量哪个是描述中的预期值呢?在这个接口的说明中其实就可以看出来:
expected - pointer to the value expected to be found in the atomic object desired - the value to store in the atomic object if it is as expected

而单纯从英文的含意来看,expected是一种客观的预测,一种合理的期望,即它是一种目标;而desired强调主观的愿望,是一种期望的结果。再和上面的英文一匹配就明白了,expected是调用者提供的期望值,而desired是符合预期情况下的存储结果。
虽然不同的平台有着细微的不同,但一般来说,软件层面上会对其进行“透明性”的屏蔽,不会被上层应用人员感知;另外一个就是硬件上,目前开发者接触的环境主要还是以X86平台为主。ARM主要在手机平台上,而这种情况下,用到CAS的机会要相当小。
在X86平台上,提供了CMPXCHG指令,这个指令是一种原子操作。所谓原子操作,就是必然会执行完成。那么这也意味着,在底层的实现机制上它们二者没有多大不同。大家这时会不会想起X86上的内存序,对,也是这样的问题。以X86平台上,基本可以不用考虑内存序(默认使用强内存序)的问题。这是不是说内存序也在影响着CAS指令呢?确实如此。常见的几种内存序与编译器及处理器性能优化对应的情况如下:

memory_order_seq_cst:全局顺序一致,要求最严,影响也最小 memory_order_acq_rel:获取-释放语义,要求一般,影响中等 memory_order_relaxed:仅保证原子性,要求最低,所以影响也最大

在AMD平台上,由于采用了LL/SC(Load-Linked/Store-Conditional)机制而且其内存序也采用了弱内存序的情况,则由于指令处理机制的并行行为,有可能导致伪失败。也就是说,这是“胎里带”,再强大的软件也搞不定。
一般来说,在非循环或严格要求情况下,推荐使用compare_exchange_strong,反之则使用compare_exchange_weak。正常情况下,在X86平台上二者几乎没有区别,但如果是在ARM等平台上,则需要考虑伪失败的情况,出于性能考虑使用compare_exchange_weak。

三、伪失败和ABA以及活锁

在CAS中,经常遇到的ABA问题,在前面分析过(多核和多CPU编程——ABA的问题,有兴趣可回看)。另外就是活锁,这个在前面也详细分析过(死锁和活锁)。此处重点分析一下伪失败问题。所谓伪失败,spurious failure,就是没有失败。没有失败的情况下应该赋新值,但伪失败也被当成失败,那么就没有达到预想的结果即没有失败也当成了失败。伪失败是compare_exchange_weak的典型特征,用来和compare_exchange_strong显式的区分开(这玩意儿有点布隆过滤器的味道啊)。怎么来理解这种情况呢?其实很简单,就是老话“人有失手,马有失蹄”。
伪失败出现的原因在于:

  1. 硬件基础环境即上面提到的AMD这类LL/SC的架构平台,它们包括PowerPC、MIPS以及RISC_V等
  2. 软件上的缓存一致性问题,哪里都有它
  3. 中断等异常行为引起的陷阱行为
  4. 多线程访问冲突(类似于1中的上层软件映射)

其实从上面的分析可看出来,伪失败基本与硬件关系紧密。象这种X86平台的就不用在考虑了。

四、应用和例程

再看一下cppreference提供的例程:

#include<atomic>#include<iostream>std::atomic<int>ai;inttst_val=4;intnew_val=5;bool exchanged=false;voidvalsout(){std::cout<<"ai= "<<ai<<" tst_val= "<<tst_val<<" new_val= "<<new_val<<" exchanged= "<<std::boolalpha<<exchanged<<"\n";}intmain(){ai=3;valsout();// tst_val != ai ==> tst_val is modifiedexchanged=ai.compare_exchange_strong(tst_val,new_val);valsout();// tst_val == ai ==> ai is modifiedexchanged=ai.compare_exchange_strong(tst_val,new_val);valsout();return0;}

运行结果:

ai= 3 tst_val= 4 new_val= 5 exchanged= false ai= 3 tst_val= 3 new_val= 5 exchanged= false ai= 5 tst_val= 3 new_val= 5 exchanged= true

其实有兴趣的可以多看一下CAS相关的例程,这个在GITHUB和其它网站上有很多,这里就不再重复贴相关的代码了。

五、总结

一个技术从不同的角度去分析,会有全新的认知。正如盲人摸象,每个人都明白,哂然一笑。但其每个人在实际的工作特别是技术开发中,经常犯这种错误。而且随着阅历的增加和技术水平的不断深入和扩展,会明白自己的局限性。这也是哲学意义上的波浪式前进,螺旋式上升。

http://www.jsqmd.com/news/416271/

相关文章:

  • 告别“全自动”幻觉!Dify v1.13.0 发布,定义企业级 AI 落地的人机协作标准
  • 落地即实用|企业健身房器材配置方案定制适配,拒绝无效投入 - 冠顶工业设备
  • oeasy Python 102 三向_旋转head_航向轴_pitch_俯仰轴_bank_横滚轴
  • [拆解LangChain执行引擎]支持自然语言查询的长期存储
  • CF555E Case of Computer Network TJ
  • 告别售后乱象|BH售后服务中心认准原厂保障更省心 - 冠顶工业设备
  • pip在venv环境安装依赖包的问题
  • 深入解析Java字符串:从不可变性到高效构建,全面掌握String核心操作
  • 鸿蒙应用开发深度探索:从基础到实战与面试准备
  • 产后焕新,温柔自愈|武汉普拉提产后修复,陪宝妈重拾轻盈体态 - 冠顶工业设备
  • 数据库-分类介绍
  • 2026年2月佛山新中式家具工厂,餐厅系列家具材质对比解析 - 品牌鉴赏师
  • 股市赚钱学概论:答疑:凭什么认为股票能涨
  • 2026年调味羊肉馅/牛肉馅厂家信誉综合参考 - 品牌宣传支持者
  • 合规好用的干式细胞复苏仪厂商推荐,上海地区靠谱的有哪些 - 工业品网
  • 想找靠谱的汽车脚垫制造厂,广州车百强值得推荐吗? - 工业推荐榜
  • 唐山舒同眼视光中心近视矫正价格多少,是否在可接受范围? - 工业设备
  • 深度学习Yolov8模型 训练无人机视角罂粟检测数据集 通过训练出的无人机航拍罂粟检测数据集权重 建立基于深度学习Yolov8罂粟识别检测系统
  • 通过aws rust sdk 连接oss
  • 20260206动态树LCT - Link
  • 最新中国十大品牌全案公司权威排行榜(附选型指南) - 品牌排行榜
  • 食品品牌全案公司推荐:新消费专精+爆品战略(机构对比) - 品牌排行榜
  • 盘点常用的满意度调研网站有哪些:头部机构汇总(选型指南) - 品牌排行榜
  • 推荐下江苏专业做流体仿真服务的公司?2026原创优选指南 - 冠顶工业设备
  • 肌肉劳损吃保健品哪个品牌好?2026专业品牌测评(选购指南) - 品牌排行榜
  • 深圳尚米网络|简历AI解析+岗位自动评估,告别手动比对 - 搭贝
  • 2026年Q1口碑好的太阳能热水器公司选哪家 - 2026年企业推荐榜
  • 棉花音乐 4.0.0 | 网盘音乐播放器 支持多种云端存储 打造无损音乐库
  • 2026年值得关注的奶咖豆品牌推荐 - 品牌排行榜
  • 2026入门手冲豆品牌推荐:新手友好风味之选 - 品牌排行榜