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

跟我学C++中级篇—悲观和乐观锁

一、悲观锁和乐观锁

在前的“并发中的锁的类型和分析”中,对C++中的锁进行了一次比较全面的说明。通过分析可以得出,C++的并行锁与其它语言的锁机制还是有着一些不同的。它更倾向于从底层描述锁的机制,而非从上层抽象的说明锁的功能。
在其它的一些语言中,可能经常看两个术语“乐观锁”和“悲观锁”。

  1. 悲观锁
    这个其实很好理解,所谓悲观就是看一切都不顺眼,不相信别人。体现在计算机中,就是所有的并发操作一定会产生冲突,要想不冲突,必须使用锁。这样才保证并发时访问数据的安全性。
    使用悲观锁的优点在于数据的强一致性得到保证,不会出现数据并发冲突导致的脏数据或重复数据,实现相对简单。但由于必须使用锁,则导致性能会明显的降低,同时降低并发性。更有可能在严重时导致死锁。它一般适于读少写多的场景时。
  2. 乐观锁
    乐观锁和悲观锁的想法正好相反,它认为世上还是好人多,出现冲突的可能是一个小概率事件。在计算的并发编程中,就是在操作数据不使用锁而只是在数据更新时检查数据是否被其它线程修改过。
    乐观锁在工作时一般要获取数据的标签(如版本号、时间戳等),用来在提交更新时进行检测,根据检测结果来进行有针对性的数据处理。它的优势在于无锁的竞争,并发性能高。特别在读多写少的情况下更有优势。也从根本上解决了死锁的可能。但当并发冲突频繁时,反复重试的开销剧增。另外,它还引入了经典的ABA和伪共享的问题。
    这里简单说明一下伪共享,伪共享指在多核或多CPU缓存中,两个没有共享(有可能冲突并发操作需要强制更新)的变量,被加载到了同一个CacheLine行中(没有共享但产生了共享,计算机认为会产生冲突,需要进行强制更新缓存操作),改变任一个后,导致其它核或CPU认为共享产生的情况。

二、C++中对应的锁

在C++中,一般来说,直接使用锁如mutex属于悲观锁,而使用CAS则被视为一种乐观锁。下面看简化后的主要代码:
悲观锁:

#include<iostream>#include<mutex>#include<thread>std::mutex mtx;intid=0;voidmutexLock(){mtx.lock();++id;mtx.unlock();}intmain(){std::threadt1(mutexLock);std::threadt2(mutexLock);t1.join();t2.join();return0;}

乐观锁:

#include<iostream>#include<atomic>#include<thread>std::atomic<int>data(0);voidcasLock(intid){intoldValue=data.load();intnewValue;do{intnewValue=++oldValue;}while(!data.compare_exchange_weak(oldValue,newValue));}intmain(){std::threadt1(casLock,0);std::threadt2(casLock,1);t1.join();t2.join();return0;}

代码非常简单,不再进行说明了。

三、应用分析

通过上面的分析和举例,已经基本明白了乐观锁和悲观锁及其在C++中的应用实现。而所谓的读多写少或读少写多,本质就是对应用哪类锁的一种偏向型分析。但实际情况中,读和写的情况经常会非常复杂。可能时多时少,也可能转换场景就有了不同的情况。而且还要考虑对错误后果忍受性及吞吐量等的业务需求限制。
但整体上,还是要把握二者性能的不同以及对数据安全性的不同为根本区别。可以动态的将二者结合起来,比如可以在金融行业中的底层操作操作使用悲观锁保证安全而上层业务使用乐观锁提高性能。另外也可以在某些场景下一开始使用乐观锁,如果检测到失败次数过多则切换为悲观锁。
常见的混合应用方法包括:

  1. 乐观锁处理性能,悲观锁处理最终确认。比如常见的秒杀就可以如此
  2. 优先使用乐观锁,发现频繁失败后转悲观锁(反之亦可)即自适应锁的升/降级。如监控系统处理系统
  3. 功能模块划分或不同阶段使用乐观锁和悲观锁。如多阶段任务处理中,前几个阶段用乐观锁而后几个阶段使用悲观锁
  4. 乐观锁尝试失败后后转悲观锁。比如用户积分等的处理

其实单纯使用乐观锁和悲观锁的应用场景也不少,比如悲观锁中的金融行业的转账、跨进程的处理等等。而乐观锁中最典型的是Redis数据库和其它一些新型数据库通过版本号等进行实时的更新处理。有过这方面开发经验的一定会非常容易理解。

四、总结

合适的就最好的。但合适本身就有不同的看法,这就需要设计和开发者仔细分析再进行取舍。不搞一言堂,不搞一刀切。哪个方法能解决问题就用哪个。从必然走向自由。

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

相关文章:

  • OpenClaw 生态网站导航推荐
  • Python电商全维数据智能分析与随机森林销量预测系统 Django 可视化 机器学习 爬虫 大数据 大模型 agent 深度学习 计算机毕业设计源码(建议收藏)✅
  • Ruby 类案例
  • Windows实操
  • 嘎嘎降AI为什么能支持9大检测平台?多平台兼容的秘密
  • 双系统安装
  • 基于 PLC 的工业锅炉过程控制程序设计及其仿真
  • 基于离散韦格纳分布(DWVD)结合卷积神经网络(CNN)与长短期记忆网络(LSTM)的故障诊断研究附Matlab代码
  • 2026年口碑好的电动喷泵推进器厂家推荐:东莞冲浪板电动喷泵/卡丁船电动喷泵推进器行业内口碑厂家推荐 - 行业平台推荐
  • OpenClaw 入门教程 | OpenClaw教程 | 第1篇
  • 673. 最长递增子序列的个数(序列dp)
  • 华沙理工大学突破性发现:让音乐生成变得可控
  • 2026年质量好的藤椒花椒油品牌推荐:四川花椒油/四川藤椒花椒油/四川无添加花椒油厂家推荐参考 - 行业平台推荐
  • JAVA开发Drools规则引擎使用
  • xxxxxxxxx
  • 2026年质量好的桥架厂家推荐:镀锌桥架厂家选购参考汇总 - 品牌宣传支持者
  • 最基础的 eBPF 示例程序 - Hello World
  • 机器人(AGV\AMR,机器狗)自动乘梯(梯控)开门(门禁又称为门控)还能加装人脸二维码刷卡识别吗?智能梯控系统通过统一主板实现电梯、门禁等设备的高效联动,采用模块化设计与物理逻辑隔离,确保安全与高效
  • 2026年知名的药厂气动物流传输系统品牌推荐:畜牧业气动物流传输系统/大连医用气动物流传输系统厂家推荐与采购指南 - 品牌宣传支持者
  • Kali与渗透测试基础
  • 2026年新疆栢顿沙发品牌推荐:栢顿家居/栢顿家居餐厅家具厂家汇总与采购指南 - 品牌宣传支持者
  • 解决超微 SuperMicro 主板风扇反复高低转速问题
  • 2026年质量好的建筑业样品检验化验传输系统品牌推荐:轮胎厂样品检验化验传输系统高口碑厂家推荐(评价高) - 品牌宣传支持者
  • 2026年口碑好的留学公司推荐:航空留学/四川航空留学优选合作机构 - 品牌宣传支持者
  • GEDFFWE[麦麦茶水间] 【每周分享】沁恒CH592F开发中遇到的ADC采样不准及解决方案
  • 从零构建企业级网页搜索:Elastic Open Crawler 架构解析与实战部署
  • 2026年热门的滑冰场设备品牌推荐:滑冰场管材优质供应商推荐参考 - 品牌宣传支持者
  • 游戏闪退/软件打不开?这款DirectX修复工具,一键搞定DLL文件缺失!
  • day10 126-130
  • 2026年评价高的地坪漆厂家推荐:水性地坪漆/车库地坪漆高评价厂家推荐 - 品牌宣传支持者