【C++】原子操作(atomic)与无锁编程学习记录
lambda
std::bind
智能指针使用
深度库基于数据结构与算法的优化
atomic 操作与多线程
数据安全 原子内存操作
设计模式:单例模式
C++11原子操作与无锁编程
https://www.jianshu.com/p/3e122ee901c5
今天我将就C++11多线程中的atomic原子操作展开讨论;比较互斥锁,自旋锁(spinlock),无锁编程的异同,并进行性能测试;最后会讨论一下内存序的问题;为了流畅阅读你最好先熟悉一下C++11 Atomic的基本操作英文文档,这里还有一份我觉得做得很用心的关于C++11并发编程的中文教程,你也可以从其中找到对应的知识点;
原子操作
我们写的代码最终都会被翻译为CPU指令,一条最简单加减法语句都有可能会被翻译成几条指令执行;为了避免语句在CPU这一层级上的指令交叉带来的行为不可知,在多线程程序设计时我们必须通过一些方式来进行规范;这里面最常见的做法就是引入互斥锁,其大概的模型就是篮球模式:几个人一起抢球,谁抢到了谁玩,玩完了再把球丢出来重新抢;但互斥锁是操作系统这一层级的,最终映射到CPU上也是一堆指令,是指令就必然会带来额外的开销;
既然CPU指令是多线程不可再分的最小单元,那我们如果有办法将代码语句和指令对应起来,不就不需要引入互斥锁从而提高性能了吗? 而这个对应关系就是所谓的原子操作;在C++11的atomic中有两种做法:
- 模拟, 比如说对于一个atomic类型,我们可以给他附带一个mutex,操作时lock/unlock一下,这种在多线程下进行访问,必然会导致线程阻塞;
- 有相应的CPU层级的对应,这就是一个标准的***lock-free***类型;
可以通过is_lock_free函数,判断一个atomic是否是lock-free类型
自旋锁
使用原子操作模拟互斥锁的行为就是自旋锁,互斥锁状态是由操作系统控制的,自旋锁的状态是程序员自己控制的;要搞清楚自旋锁我们首先要搞清楚自旋锁模型,常用的自旋锁模型有:
- TAS, Test-and-set,有且只有atomic_flag类型与之对应
- CAS, Compare-and-swap,对应atomic的compare_exchange_strong 和 compare_exchange_weak,这两个版本的区别是:Weak版本如果数据符合条件被修改,其也可能返回false,就好像不符合修改状态一致;而Strong版本不会有这个问题,但在某些平台上Strong版本比Weak版本慢 [注:在x86平台我没发现他们之间有任何性能差距];绝大多数情况下,我们应该优先选择使用Strong版本;
我针对这两种模型分别实现了两个版本的自旋锁,最终代码可以在性能测试章节中找到,这里我们要注意以下问题:
LOCK时自旋锁是自己轮询状态,如果不引入中断机制,会有大量计算资源浪费到轮询本身上;常用的做法是使用yield切换到其他线程执行,或直接使用sleep暂停当前线程.
无锁编程
如果看了CAS实现的自旋锁代码会发现其有些别扭:每次都需要去重置exp的状态为false;CAS虽然也能实现自旋锁,但通常被我们用来进行无锁编程;
https://www.jianshu.com/p/3e122ee901c5
不难看出,其实所谓无锁编程只是将多条指令合并成了一条指令形成一个逻辑完备的最小单元,通过兼容CPU指令执行逻辑形成的一种多线程编程模型;结束了吗,再等等,使用上面的代码,有很大的几率出delete不存在的内存,或内存被多次delete的错误。
ABA问题
维基百科: ABA problem,如果有两个线程[1&2]操作上面的堆栈,初始状态有2个元素: top->A->B,线程1执行pop操作,在CAS前进行线程切换:
内存模型
该模型最直接的应用就是通过某一个内存的操作状态来判断,一些操作的顺序,从而达到操作交叉的灵活安排,比如预处理或者升读生成!
C++11原子操作的很多函数都有个std::memory_order参数,这个参数就是这里所说的内存模型,其并不是类似POD的内存布局,而是一种数据同步模型,准确说法应该是**储存一致性模型,其作用是对同一时间的读写操作进行排序;**C++11中一个定义了6种类型,我们可以将其分为4类,下面我从我的角度以普通程序员能理解的语言描述一下,具体的可以参见 C++11 Memory Order:
说到内存模型,就不得不提一下经常被大家误用的 *volatile* 关键字,这个关键字仅仅保证:数据只在内存中读写,直接操作它既不能保证操作是atomic的,也不能保证Memory Order;其实在我理解中,这个应该是嵌入式,内核或驱动程序员专用关键字:),当然如果在竞争不敏感的环境中用来做flag用一下也没太大问题.
最后要说一下x86体系中Release-Acquire是自动获取的,最终形成一个***memory_order_seq_cst*模型;因此绝大多数情况下*memory_order_relaxed***其实并没有什么用.
【C++】原子操作(atomic)与无锁编程学习记录相关推荐
- 【C++】多线程与原子操作和无锁编程【五】
[C++]多线程与原子操作和无锁编程[五] 1.何为原子操作 前面介绍了多线程间是通过互斥锁与条件变量来保证共享数据的同步的,互斥锁主要是针对过程加锁来实现对共享资源的排他性访问.很多时候,对共享资源 ...
- 浅谈Linux内核无锁编程原理
非阻塞型同步 (Non-blocking Synchronization) 简介 如何正确有效的保护共享数据是编写并行程序必须面临的一个难题,通常的手段就是同步.同步可分为阻塞型同步(Blocking ...
- 【翻译】RUST无锁编程
本文内容译自Lock-freedom without garbage collection,中间有少量自己的修改. 人们普遍认为,垃圾收集的一个优点是易于构建高性能的无锁数据结构.对这些数据结构进行手 ...
- 交易系统开发技能及面试之无锁编程(Lock-free)
目录 概要 Q1 什么是atomic? Q2 alignas 关键字 Q3 C++的内存模型 relaxed ordering, release-acquire ordering, sequentia ...
- 无锁编程与有锁编程的效率总结、无锁队列的实现(c语言)
1.无锁编程与有锁编程的效率 无锁编程,即通过CAS原子操作去控制线程的同步.如果你还不知道什么使CAS原子操作,建议先去查看相关资料,这一方面的资料网络上有很多. CAS实现的是硬件级的互斥,在线程 ...
- 【算法】CAS的实现和无锁编程
CAS(Compare and swap,比较与交换) 是一种有名的无锁算法.比较与交换,先比较,发现与预期一致,说明没有其他线程改动过,于是再交换.如果与预期不一致说明改动过,就再来一次. 与各类锁 ...
- Cpp / 无锁编程
无锁编程,就是编译器不再使用系统中关于锁的 API,而是直接通过使用缓存一致性等算法达到锁的目的的一种编程. 可以使用 std::atomic<T> 系列和 __sync_val_comp ...
- 无锁编程(Lock Free)框架 系列文章
无锁编程(Lock Free)框架 系列文章: 1 前置知识:伪共享 原理 & 实战 2 disruptor 使用和原理 图解 3 akka 使用和原理 图解 4 camel 使用和 原理 图 ...
- 我是如何一步步的在并行编程中将lock锁次数降到最低实现无锁编程
在并行编程中,经常会遇到多线程间操作共享集合的问题,很多时候大家都很难逃避这个问题做到一种无锁编程状态,你也知道一旦给共享集合套上lock之后,并发和伸缩能力往往会造成很大影响,这篇就来谈谈如何尽可能 ...
最新文章
- 怎么计算另一个表格内某几列的和_Excel 函数(一) – 用 evaluate 函数自动计算
- Nginx文件描述符泄露?浅析FD_CLOEXEC文件描述符标志
- Azure Redis 系列之 Azure Redis部署
- Python 使用穷举法求两个数的最大公约数。
- java 关键字volatile的作用
- ToolProvider.getSystemJavaCompiler() return null 的解决方法
- java邮箱_java发送邮件(qq邮箱)
- axi时序图_深入 AXI4总线(E3)实战:制作一个 AXI 接口 IP
- 阿里最喜欢问的多线程顺序打印的5种解法!
- UC浏览器云标签怎么用 UC浏览器云标签使用方法
- 深度学习(七十四)半监督Mean teachers
- 将txt文件转换成xlsx文件及用matlab读取xlsx
- 转:Apache2 httpd.conf 中文版
- matlab计算中值 众值,基于GPS运动摄像机数据确定道路圆曲线半径及行车视距的方法与流程...
- 3D机器学习(4):pytorch入门3:张量的拼接与拆分、张量的运算、张量的统计
- SAP MM 采购信息记录中价格单位转换因子的修改
- 认识RAM、ROM、CACHE
- 微信小程序、微信小游戏作品汇总合集,各种好玩的小程序
- python——不同路径 ||
- ADS集成开发环境介绍
热门文章
- windows 服务程序学习心得
- 隐藏在手机中的第二个操作系统
- word文档docx解密去除限制,word文档docx复制打印限制怎么解除?
- tomcat服务器的搭建
- python模块之 异步channels实现
- 《UC-Net:Uncertainty Inspired RGB-D Saliency Detection via Conditional Variational Autoencoders》论文笔记
- 给小朋友讲故事——谈谈杨振宁先生第三部分终篇(七次提交稿)
- Vulkan_顶点着色器特效1(流动的水面或飘扬的红旗)
- Unity 之 ShaderGraph 实现小旗随风飘扬效果入门级教程
- 理解网络中的控制平面和转发平面,你就不再是网络小白了