• atomic介绍

atomic对int、char、bool等数据结构进行了原子性封装,在多线程环境中,对std::atomic对象的访问不会造成竞争-冒险。利用std::atomic可实现数据结构的无锁设计。

所谓的原子操作,取的就是“原子是最小的、不可分割的最小个体”的意义,它表示在多个线程访问同一个全局资源的时候,能够确保所有其他的线程都不在同一时间内访问相同的资源。也就是他确保了在同一时刻只有唯一的线程对这个资源进行访问。这有点类似互斥对象对共享资源的访问的保护,但是原子操作更加接近底层,因而效率更高。

在以往的C++标准中并没有对原子操作进行规定,我们往往是使用汇编语言,或者是借助第三方的线程库,例如intel的pthread来实现。在新标准C++11,引入了原子操作的概念,并通过这个新的头文件提供了多种原子操作数据类型,例如,atomic_bool,atomic_int等等,如果我们在多个线程中对这些类型的共享资源进行操作,编译器将保证这些操作都是原子性的,也就是说,确保任意时刻只有一个线程对这个资源进行访问,编译器将保证,多个线程访问这个共享资源的正确性。从而避免了锁的使用,提高了效率。

  • atomic高效体现

加锁不使用atomic:

#include <iostream>
#include <ctime>
#include <mutex>
#include <vector>
#include <thread>std::mutex mtx;
size_t count = 0;void threadFun()
{for (int i = 0; i < 10000; i++){// 防止多个线程同时访问同一资源std::unique_lock<std::mutex> lock(mtx);count++;}
}int main(void)
{clock_t start_time = clock();// 启动多个线程std::vector<std::thread> threads;for (int i = 0; i < 10; i++)threads.push_back(std::thread(threadFun));for (auto&thad : threads)thad.join();// 检测count是否正确 10000*10 = 100000std::cout << "count number:" << count << std::endl;clock_t end_time = clock();std::cout << "耗时:" << end_time - start_time << "ms" << std::endl;return 0;
}

运行结果

使用atomic:

#include <iostream>
#include <ctime>
#include <vector>
#include <thread>
#include <atomic>std::atomic<size_t> count(0);void threadFun()
{for (int i = 0; i < 10000; i++)count++;
}int main(void)
{clock_t start_time = clock();// 启动多个线程std::vector<std::thread> threads;for (int i = 0; i < 10; i++)threads.push_back(std::thread(threadFun));for (auto&thad : threads)thad.join();// 检测count是否正确 10000*10 = 100000std::cout << "count number:" << count << std::endl;clock_t end_time = clock();std::cout << "耗时:" << end_time - start_time << "ms" << std::endl;return 0;
}

运行结果

总结

从上面的截图可以发现,第一张图用时2439ms,第二张图用时13ms,使用原子操作能大大的提高程序的运行效率。

附:很多读者不理解为什么在后面另起一个for循环进行join,对于这个问题,我希望读者自己先了解下join的用法。

实际上线程在上一个for循环创建的时候就已经开始运行了,join只是为了阻塞主线程,用于等待所有子线程完成,不然子线程还未执行完,主线程就已经结束了(同时也方便我这边计时)。

同时为什么不能创建线程后立刻join,也是上面说的join会阻塞主线程,主线程被阻塞了,for循环就得等子线程执行完后才会继续创建新的线程了,这种压根不涉及并发执行,不涉及资源竞争的问题,是串行的。

  • 参考文档

博客地址:https://blog.csdn.net/yockie/article/details/8838686

C++11之atomic原子操作相关推荐

  1. C++11开发中的Atomic原子操作

    C++11开发中的Atomic原子操作 Nicol的博客铭 原文  https://taozj.org/2016/09/C-11%E5%BC%80%E5%8F%91%E4%B8%AD%E7%9A%84 ...

  2. std::atomic原子操作

    1.原子操作介绍 在多线程编程中,经常使用互斥锁锁住一段代码块,实现线程同步.原子操作可以看成是对变量的互斥锁.比如程序中一个线程读取一个变量,另一个线程修改该变量的值,那么采用原子操作可以不用添加互 ...

  3. go atomic 原子操作

    在 go 语言 string 类型思考 中有说到 -race 竞态检测,多个 goroutine 并发读写同一个变量是会触发.竞态竞争导致的问题是:结果不可控,你也无法预料最终的结果是什么. 比较棘手 ...

  4. 2-2-3-3、Atomic原子操作类详解

    目录 Atomic原子操作类 作用 分类 基本类型 引用类型 数组类型 对象属性原子修改器 原子类型累加器(jdk1.8增加的类) 作用 性能测试 条件>>>>>> ...

  5. Concurrent——Atomic原子操作类

    转载自https://blog.csdn.net/sdlyjzh/article/details/78587777 打算把Concurrent包下面的一些类整理一下.今天先从最简单的开始,Atomic ...

  6. Multi-thread--C++11中atomic的使用

    原子库为细粒度的原子操作提供组件,允许无锁并发编程.涉及同一对象的每个原子操作,相对于任何其他原子操作是不可分的.原子对象不具有数据竞争(data race).原子类型对象的主要特点就是从不同线程访问 ...

  7. 利用C++11原子量atomic实现自旋锁详解

    一.自旋锁 自旋锁是一种基础的同步原语,用于保障对共享数据的互斥访问.与互斥锁的相比,在获取锁失败的时候不会使得线程阻塞而是一直自旋尝试获取锁.当线程等待自旋锁的时候,CPU不能做其他事情,而是一直处 ...

  8. STL::atomic原子操作

    原文地址:https://www.cnblogs.com/haippy/p/3252056.html C++11 并发指南已经写了 5 章,前五章重点介绍了多线程编程方面的内容,但大部分内容只涉及多线 ...

  9. C++11多线程的原子操作

    原子操作是同时只能有一个线程执行一个操作,不用使用互斥量即可实现,但是速度慢,而且一般只支持原生的类型,不够灵活.更多的用处是作为信号量进行使用. 示例代码,以int为例子: #include < ...

最新文章

  1. NSString类详解
  2. API聚合网关技术选型参考-网友实战-使用协程
  3. 不懂编程可以自学python吗-给初学python的朋友的一些忠告和建议
  4. python上海培训哪里比较好-上海Python培训哪家强
  5. 一次远程支持事故的教训,与大家分享
  6. 2019年3月未来教育计算机二级题库,2019年3月计算机二Access考试操作模拟试题001...
  7. Docker - Docker中搭建MySQL主从
  8. which 命令
  9. python判断文件是否存在 中文_python如何判断文件是否存在
  10. 麦当劳降价“过冬” 一夜回到十年前(转)
  11. 最长公共子序列php,动态规划(最长公共子序列LCS)
  12. 不能从远程创建com+对象_链路追踪SkyWalking源码分析——Collector Remote远程通信服务...
  13. Centos7.x 安装Kubernetes(K8s) 1.16.2 kubeadm kubelet kubectl 单机版 2019-10-20更新
  14. strpos php 中文,php strpos是什么
  15. android 2d mmorpg,20款不可错过,史上最佳的MMORPG游戏(下)
  16. Python数据分析实战之北京二手房房价分析
  17. 数据保护与云不离不弃,云中护航渐成行业主旋律
  18. 音频信号转为开关控制信号_盘点模拟量信号和开关量信号区别与应用
  19. type-c连接器的激光焊锡工艺应用
  20. 图像去模糊(维纳滤波)

热门文章

  1. Container启动
  2. kdevtmpfsi 处理(挖矿病毒清除)
  3. 缺少对象 index.php 行123,Microsoft VBScript 运行时错误 (0x800A01A8)缺少对象: ''
  4. 在Android Studio上魅族手机、华为手机无法打印Log
  5. NOIP 2010 普及组 复赛 sanguo 三国游戏
  6. 计算机学术期刊排名:Computer Science Journal Rankings(zz)
  7. 判别分析分为r型和q型吗_聚类分析与判别分析
  8. vue 自定义弹窗的使用
  9. 全球多媒体软件行业调研及趋势分析报告
  10. php assoc 循环,PHP嵌套While循环不适用于mysql_fetch_assoc