1. std::atomic_flag

  std::atomic_flag是一个原子的布尔类型,可支持两种原子操作:

  • test_and_set, 如果atomic_flag对象被设置,则返回true; 如果atomic_flag对象未被设置,则设置之,返回false
  • clear. 清楚atomic_flag对象

  std::atomic_flag可用于多线程之间的同步操作,类似于linux中的信号量。使用atomic_flag可实现mutex.

  1. #include <iostream>
  2. #include <atomic>
  3. #include <vector>
  4. #include <thread>
  5. #include <sstream>
  6.  
  7. std::atomic_flag lock = ATOMIC_FLAG_INIT;
  8. std::stringstream stream;
  9.  
  10. void append_numer(int x)
  11. {
  12. while (lock.test_and_set());
  13. stream << "thread#" << x << "\n";
  14. lock.clear();
  15. }
  16.  
  17. int main()
  18. {
  19. std::vector<std::thread> ths;
  20. for (int i=; i<; i++)
  21. ths.push_back(std::thread(append_numer, i));
  22. for (int i=; i<; i++)
  23. ths[i].join();
  24. std::cout << stream.str();
  25. return ;
  26. }

 

2. std::atomic

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

  1. #include <iostream>
  2. #include <atomic>
  3. #include <vector>
  4. #include <thread>
  5. #include <sstream>
  6.  
  7. std::atomic<bool> ready(false);
  8. std::atomic_flag winner = ATOMIC_FLAG_INIT;
  9.  
  10. void count1m(int i)
  11. {
  12. while (!ready);
  13. for (int i=; i<; i++);
  14. if (!winner.test_and_set())
  15. std::cout << "winner: " << i << std::endl;
  16. }
  17.  
  18. int main()
  19. {
  20. std::vector<std::thread> ths;
  21. for (int i=; i<; i++)
  22. ths.push_back(std::thread(count1m, i));
  23. ready = true;
  24. for (int i=; i<; i++)
  25. ths[i].join();
  26. return ;
  27. }

在上例中,执行read=true之后,所有线程结束空等。winner被初始化为ATOMIC_FLAG_INIT,最先执行winner.test_and_set并返回false的线程为winner。

  1. #include <iostream>
  2. #include <atomic>
  3. #include <vector>
  4. #include <thread>
  5. #include <sstream>
  6.  
  7. std::atomic<int> foo();
  8.  
  9. void set_foo(int x)
  10. {
  11. foo = x;
  12. }
  13.  
  14. void print_foo()
  15. {
  16. while (foo == )
  17. {
  18. std::this_thread::yield();
  19. }
  20. std::cout << "x: " << foo << std::endl;
  21. }
  22. int main()
  23. {
  24. std::thread print_th(print_foo);
  25. std::thread set_th(set_foo, );
  26. print_th.join();
  27. set_th.join();
  28. return ;
  29. }

在上例中,set_foo用于设置atomic<int>对象的值,print_foo用于打印atomic<int>对象的值。std::atomic对象的值的读取和写入可使用load和store实现。

  1. #include <iostream>
  2. #include <cassert>
  3. #include <atomic>
  4. #include <vector>
  5. #include <unistd.h>
  6. #include <thread>
  7. #include <sstream>
  8.  
  9. std::atomic<int> foo();
  10. std::atomic_flag lock = ATOMIC_FLAG_INIT;
  11.  
  12. void add_foo()
  13. {
  14. while ()
  15. {
  16. foo++;
  17. // foo = foo + 1;
  18. while (lock.test_and_set());
  19. std::cout <<"add: " << foo << std::endl;
  20. lock.clear();
  21. usleep();
  22. }
  23. }
  24.  
  25. void sub_foo()
  26. {
  27. while ()
  28. {
  29. foo--;
  30. // foo = foo - 1;
  31. while (lock.test_and_set());
  32. std::cout << "sub: " << foo << std::endl;
  33. lock.clear();
  34. usleep();
  35. }
  36. }
  37. int main()
  38. {
  39. std::thread th2 = std::thread(add_foo);
  40. std::thread th1 = std::thread(sub_foo);
  41. th1.join();
  42. th2.join();
  43. return ;
  44. }

atomic<int>支持++和--的原子操作。

(其他可参考 https://blog.csdn.net/fengbingchun/article/details/73436710)

C++11之 std::atomic (不用锁实现线程互斥)的更多相关文章

  1. C++11 并发指南六(atomic 类型详解三 std::atomic (续))

    C++11 并发指南六( <atomic> 类型详解二 std::atomic ) 介绍了基本的原子类型 std::atomic 的用法,本节我会给大家介绍C++11 标准库中的 std: ...

  2. C++11 并发指南六( <atomic> 类型详解二 std::atomic )

    C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)  一文介绍了 C++11 中最简单的原子类型 std::atomic_flag,但是 std::atomic_flag ...

  3. 第31课 std::atomic原子变量

    一. std::atomic_flag和std::atomic (一)std::atomic_flag 1. std::atomic_flag是一个bool类型的原子变量,它有两个状态set和clea ...

  4. std::atomic和std::mutex区别

    ​ ​std::atomic介绍​ ​模板类std::atomic是C++11提供的原子操作类型,头文件 #include<atomic>.​在多线程调用下,利用std::atomic可实 ...

  5. 用C++11的std::async代替线程的创建

    c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int n); std::thread t(f, n + 1); t.join(); 但是线程毕竟是属于比 ...

  6. C++11多线程std::thread的简单使用

    在cocos2dx 2.0时代,我们使用的是pthread库,是一套用户级线程库,被广泛地使用在跨平台应用上.但在cocos2dx 3.0中并未发现有pthread的支持文件,原来c++11中已经拥有 ...

  7. C++11 使用 std::async创建异步程序

    c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int n); std::thread t(f, n + 1); t.join(); 但是线程毕竟是属于比 ...

  8. (原创)用C++11的std::async代替线程的创建

    c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int n); std::thread t(f, n + ); t.join(); 但是线程毕竟是属于比较 ...

  9. Cocos2dx 3.0 过渡篇(二十七)C++11多线程std::thread的简单使用(下)

    本篇接上篇继续讲:上篇传送门:http://blog.csdn.net/star530/article/details/24186783 简单的东西我都说的几乎相同了,想挖点深的差点把自己给填进去. ...

随机推荐

  1. sqlserver 中常见的函数 数学函数

    create table testnum( ID int identity(1,1), num float) insert testnum values (1) insert testnum valu ...

  2. Cordova+Vue快速搭建Hybrid App

    前言 最近项目迭代需要开发一个app,由于项目组其他系统前端技术栈都是Vue,所以自己在需求评估的时候就初步敲定了Cordova+Vue的前端架构,后来查阅了不少资料,也掉了不少坑,这里总结一下,也算 ...

  3. Golang的session管理器

    对于一些需要对用户进行管理(比如验证操作的权限等)的站点来说,session管理器是必不可少的.下面实现了一个线程安全的简单session管理类.生产环境:golang1.4.2+win7x64gol ...

  4. jquery 手机获取验证码计时

    html: <input type="text" class="codeText" id="txtverifycode" />  ...

  5. Jmeter 接口测试知识梳理——持续集成篇

    Jmeter 使用也有很长时间了,但是一直没有做一下知识梳理,近期会对公司同事做一下这方面的培训,借此机会,把使用过程中应用到的知识,或是遇到的问题,整理出来,方便大家学习! Jmeter + Ant ...

  6. lua闭包实现迭代器遍历数组

    --实现访问数组的迭代器 function visit(t) return function() i = i + return t[i] end end --要访问的数组 ,,,} itor = vi ...

  7. 第 6 章 存储 - 040 - docker managed volume

    docker managed volume 与 bind mount 在最大区别是不需要指定 mount 源,指明 mount point 就行了 通过 -v 告诉 docker 需要一个 data ...

  8. linux下安装nginx以及常用命令指南

    安装nginx之前,要先在服务器上安装nginx运行所需要的依赖包 目录选择:一般选择 "/usr/local/" 1.安装PCRE库 离线安装包:https://pan.baid ...

  9. PHP中如何命令行

    PHP中如何命令行 一.总结 一句话总结:配置php系统环境,然后命令行中运行 php -f 文件名即可 配置php系统环境 php_-f_文件名 例如: 1.三种运行php的方式? 运行文件_-f ...

  10. ubuntu12.04 安装CAJViewer-ubuntu(待解决)

    ubuntu12.04测试通过 1.sudo apt-get install wine 2.unzip CAJViewer-ubuntu12.04版.zip 3.wine CAJVieweru.exe