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 简单的东西我都说的几乎相同了,想挖点深的差点把自己给填进去. ...
随机推荐
- CAS 是什么
CAS是英文单词Compare And Swap的缩写,翻译过来就是比较并替换. CAS机制当中使用了3个基本操作数:内存地址V,旧的预期值A,要修改的新值B. 更新一个变量的时候,只有当变量的预期值 ...
- main方法介绍
main方法是程序的入口点,程序从这里开始,也是从这里结束. 执行过程:程序在执行编译的过程中先找main方法,然后执行main‘{’下的第一行代码,以此执行,如果遇到main方法中有调用其他的方法时 ...
- 《剑指offer》第五十七题(和为s的两个数字)
// 面试题57(一):和为s的两个数字 // 题目:输入一个递增排序的数组和一个数字s,在数组中查找两个数,使得它们 // 的和正好是s.如果有多对数字的和等于s,输出任意一对即可. #includ ...
- vuex深入理解 modules
一.什么是module? 背景:在Vue中State使用是单一状态树结构,应该的所有的状态都放在state里面,如果项目比较复杂,那state是一个很大的对象,store对象也将对变得非常大,难于管理 ...
- postMan用法
增加: 删除: 更改: 查询:
- Python数据分析-Day1-Numpy模块
1.numpy.genfromtxt读取txt文件 import numpyworld_alcohol = numpy.genfromtxt("world_alcohol.txt" ...
- word2010怎么把白色方框变成黑色方框?
word2010怎么把白色方框变成黑色方框? 打开Word 2010文档,选中第四个白色方框. 切换到“插入”功能区,在符号选项组单击“符号”按钮,出来的窗口单击“其他符号”. 在“符号”选项卡单 ...
- Enable SMB2 on the Client
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\LanmanWorkstation edit DependOnService and add ...
- gooreplacer 很好用
国内上 StackOverflow, hackernews 之类的站点会慢. 因为页面里有链接指向 google 谷歌, 会被墙. 于是拖累了整个页面的显示. gooreplacer 可以把这些被墙连 ...
- one-class logistic regression (OCLR)
ONE-CLASS DETECTION OF CELL STATES IN TUMOR SUBTYPES Machine Learning Identifies Stemness Features A ...