C++11之 std::atomic (不用锁实现线程互斥)
- 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.
- #include <iostream>
- #include <atomic>
- #include <vector>
- #include <thread>
- #include <sstream>
- std::atomic_flag lock = ATOMIC_FLAG_INIT;
- std::stringstream stream;
- void append_numer(int x)
- {
- while (lock.test_and_set());
- stream << "thread#" << x << "\n";
- lock.clear();
- }
- int main()
- {
- std::vector<std::thread> ths;
- for (int i=; i<; i++)
- ths.push_back(std::thread(append_numer, i));
- for (int i=; i<; i++)
- ths[i].join();
- std::cout << stream.str();
- return ;
- }
2. std::atomic
std::atomic对int, char, bool等数据结构进行原子性封装,在多线程环境中,对std::atomic对象的访问不会造成竞争-冒险。利用std::atomic可实现数据结构的无锁设计。
- #include <iostream>
- #include <atomic>
- #include <vector>
- #include <thread>
- #include <sstream>
- std::atomic<bool> ready(false);
- std::atomic_flag winner = ATOMIC_FLAG_INIT;
- void count1m(int i)
- {
- while (!ready);
- for (int i=; i<; i++);
- if (!winner.test_and_set())
- std::cout << "winner: " << i << std::endl;
- }
- int main()
- {
- std::vector<std::thread> ths;
- for (int i=; i<; i++)
- ths.push_back(std::thread(count1m, i));
- ready = true;
- for (int i=; i<; i++)
- ths[i].join();
- return ;
- }
在上例中,执行read=true之后,所有线程结束空等。winner被初始化为ATOMIC_FLAG_INIT,最先执行winner.test_and_set并返回false的线程为winner。
- #include <iostream>
- #include <atomic>
- #include <vector>
- #include <thread>
- #include <sstream>
- std::atomic<int> foo();
- void set_foo(int x)
- {
- foo = x;
- }
- void print_foo()
- {
- while (foo == )
- {
- std::this_thread::yield();
- }
- std::cout << "x: " << foo << std::endl;
- }
- int main()
- {
- std::thread print_th(print_foo);
- std::thread set_th(set_foo, );
- print_th.join();
- set_th.join();
- return ;
- }
在上例中,set_foo用于设置atomic<int>对象的值,print_foo用于打印atomic<int>对象的值。std::atomic对象的值的读取和写入可使用load和store实现。
- #include <iostream>
- #include <cassert>
- #include <atomic>
- #include <vector>
- #include <unistd.h>
- #include <thread>
- #include <sstream>
- std::atomic<int> foo();
- std::atomic_flag lock = ATOMIC_FLAG_INIT;
- void add_foo()
- {
- while ()
- {
- foo++;
- // foo = foo + 1;
- while (lock.test_and_set());
- std::cout <<"add: " << foo << std::endl;
- lock.clear();
- usleep();
- }
- }
- void sub_foo()
- {
- while ()
- {
- foo--;
- // foo = foo - 1;
- while (lock.test_and_set());
- std::cout << "sub: " << foo << std::endl;
- lock.clear();
- usleep();
- }
- }
- int main()
- {
- std::thread th2 = std::thread(add_foo);
- std::thread th1 = std::thread(sub_foo);
- th1.join();
- th2.join();
- return ;
- }
atomic<int>支持++和--的原子操作。
(其他可参考 https://blog.csdn.net/fengbingchun/article/details/73436710)
C++11之 std::atomic (不用锁实现线程互斥)的更多相关文章
- C++11 并发指南六(atomic 类型详解三 std::atomic (续))
C++11 并发指南六( <atomic> 类型详解二 std::atomic ) 介绍了基本的原子类型 std::atomic 的用法,本节我会给大家介绍C++11 标准库中的 std: ...
- C++11 并发指南六( <atomic> 类型详解二 std::atomic )
C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍) 一文介绍了 C++11 中最简单的原子类型 std::atomic_flag,但是 std::atomic_flag ...
- 第31课 std::atomic原子变量
一. std::atomic_flag和std::atomic (一)std::atomic_flag 1. std::atomic_flag是一个bool类型的原子变量,它有两个状态set和clea ...
- std::atomic和std::mutex区别
std::atomic介绍 模板类std::atomic是C++11提供的原子操作类型,头文件 #include<atomic>.在多线程调用下,利用std::atomic可实 ...
- 用C++11的std::async代替线程的创建
c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int n); std::thread t(f, n + 1); t.join(); 但是线程毕竟是属于比 ...
- C++11多线程std::thread的简单使用
在cocos2dx 2.0时代,我们使用的是pthread库,是一套用户级线程库,被广泛地使用在跨平台应用上.但在cocos2dx 3.0中并未发现有pthread的支持文件,原来c++11中已经拥有 ...
- C++11 使用 std::async创建异步程序
c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int n); std::thread t(f, n + 1); t.join(); 但是线程毕竟是属于比 ...
- (原创)用C++11的std::async代替线程的创建
c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int n); std::thread t(f, n + ); t.join(); 但是线程毕竟是属于比较 ...
- Cocos2dx 3.0 过渡篇(二十七)C++11多线程std::thread的简单使用(下)
本篇接上篇继续讲:上篇传送门:http://blog.csdn.net/star530/article/details/24186783 简单的东西我都说的几乎相同了,想挖点深的差点把自己给填进去. ...
随机推荐
- sqlserver 中常见的函数 数学函数
create table testnum( ID int identity(1,1), num float) insert testnum values (1) insert testnum valu ...
- Cordova+Vue快速搭建Hybrid App
前言 最近项目迭代需要开发一个app,由于项目组其他系统前端技术栈都是Vue,所以自己在需求评估的时候就初步敲定了Cordova+Vue的前端架构,后来查阅了不少资料,也掉了不少坑,这里总结一下,也算 ...
- Golang的session管理器
对于一些需要对用户进行管理(比如验证操作的权限等)的站点来说,session管理器是必不可少的.下面实现了一个线程安全的简单session管理类.生产环境:golang1.4.2+win7x64gol ...
- jquery 手机获取验证码计时
html: <input type="text" class="codeText" id="txtverifycode" /> ...
- Jmeter 接口测试知识梳理——持续集成篇
Jmeter 使用也有很长时间了,但是一直没有做一下知识梳理,近期会对公司同事做一下这方面的培训,借此机会,把使用过程中应用到的知识,或是遇到的问题,整理出来,方便大家学习! Jmeter + Ant ...
- lua闭包实现迭代器遍历数组
--实现访问数组的迭代器 function visit(t) return function() i = i + return t[i] end end --要访问的数组 ,,,} itor = vi ...
- 第 6 章 存储 - 040 - docker managed volume
docker managed volume 与 bind mount 在最大区别是不需要指定 mount 源,指明 mount point 就行了 通过 -v 告诉 docker 需要一个 data ...
- linux下安装nginx以及常用命令指南
安装nginx之前,要先在服务器上安装nginx运行所需要的依赖包 目录选择:一般选择 "/usr/local/" 1.安装PCRE库 离线安装包:https://pan.baid ...
- PHP中如何命令行
PHP中如何命令行 一.总结 一句话总结:配置php系统环境,然后命令行中运行 php -f 文件名即可 配置php系统环境 php_-f_文件名 例如: 1.三种运行php的方式? 运行文件_-f ...
- ubuntu12.04 安装CAJViewer-ubuntu(待解决)
ubuntu12.04测试通过 1.sudo apt-get install wine 2.unzip CAJViewer-ubuntu12.04版.zip 3.wine CAJVieweru.exe