• 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. linux useradd
  2. erlang精要(7)-模块
  3. 流水线可靠数据传输协议
  4. 面试官:“你大学做过真实项目吗?”
  5. GARFIELD@02-24-2005
  6. Linux开关命令(shutdown,reboot,halt,init)
  7. “做实体店,已经是绝路了吗?”
  8. Linux 系统服务漏洞PwnKit 已存在12年,可获得所有主流发布版本的root 权限
  9. Android or java https ssl exception
  10. JQuery+div+css实现无限级联树
  11. 搜狐邮箱怎么开启pop3服务器,POP3是什么?怎样开通POP3?
  12. 阐述游戏关卡设计中的色彩理论
  13. Top Trending Libraries of 2021,PaddleOCR再开源8大前沿顶会论文模型
  14. php网站制作(6)-php 学习摘记
  15. SpringBoot项目端点配置
  16. python专业版和普通版_Pycharm专业版 社区版 教育版区别
  17. idea有时不进断点的原因
  18. C#笔记-PictureBox.SizeMode属性详解
  19. java获取视频第一帧工具类
  20. ERP采购管理系统软件

热门文章

  1. STM32基础知识点总结
  2. 将24小时进制转化为12小时进制
  3. Multi-Runtime Microservices Architecture
  4. 高速数据处理平台学习资料第3篇:基于双TMS320C6678+双XC6VSX315T的6U VPX高速数据处理平台
  5. 充电电阻和储能电容引发的变频器故障
  6. 在springboot中使用JWT自定义生成Token信息,接口请求时校验Token(在Shiro基础上)
  7. 开源免费代码_02_单摇杆远程遥控小车,基于Arduino的ESP-NOW,ESP32发送指令、ESP32接收指令,实现小车毫秒级完美控制_公羽兴
  8. async await 的 实质 本质
  9. docsify安装(线上文档)
  10. 【星球】【slam】研讨会(4)你真的适合读博吗?