atomic原子操作
C++中对共享数据的存取在并发条件下可能会引起data race的未定义行为,需要限制并发程序以某种特定的顺序执行,有两种方式:1.使用mutex保护共享数据; 2.原子操作
原子操作:针对原子类型操作要不一步完成,要么不做,不可能出现操作一半被切换CPU,这样防止由于多线程指令交叉执行带来的可能错误。非原子操作下,某个线程可能看见的是一个其它线程操作未完成的数据。
一、atomic_flag
std::atomic_flag是一个bool原子类型,有两个状态:set(flag=true) 和 clear(flag=false),必须被ATOMIC_FLAG_INIT初始化,此时flag为clear状态,相当于静态初始化。
一旦atomic_flag初始化后只有三个操作:test_and_set,clear,析构,均是原子化操作。
test_and_set检查flag是否被设置,若被设置直接返回true,若没有设置则设置flag为true后再返回false。
clear()清除flag标志即flag=false。
不支持拷贝、赋值等操作,这和所有atomic类型一样,因为两个原子类型之间操作不能保证原子化。atomic_flag的可操作性不强导致其应用局限性,还不如atomic<bool>。
使用atomic_flag作为简单的自旋锁例子:每个线程先将atomic_flag设为true,再设为false
atomic_flag lock_stream = ATOMIC_FLAG_INIT;//flag处于clear状态,没有被设置过
stringstream stream; void append_number(int x)
{
while (lock_stream.test_and_set()) {}//检查并设置是个原子操作,如以前没有设置过则退出循环,
//每个线程都等待前面一个线程将lock_stream状态清楚后跳出循环,第一个线程除外,此时lock_stream为clear状态
stream << "thread #" << x << '\n';
lock_stream.clear();
} int main()
{
vector<std::thread> threads;
for (int i = ; i <= ; ++i)
threads.push_back(thread(append_number, i));
for (auto& th : threads)
th.join();
cout << stream.str(); system("pause");
return ;
}
二、 atomic<T>模板类
atomic<T>生成一个T类型的原子对象,并提供了系列原子操作函数。其中T是trivially copyable type,满足:要么全部定义了拷贝/移动/赋值函数,要么全部没定义;没有虚成员;基类或其它任何非static成员都是trivally copyable。典型的内置类型bool、int等属于trivally copyable。再如class triviall{public: int x};也是。
struct Node
{
int value;
Node* next;
Node(int val,Node* p):value(val),next(p){}
}; atomic<Node*> list_head; void append(int val)
{ // append an element to the list
Node* newNode = new Node(val,list_head );
// next is the same as: list_head = newNode, but in a thread-safe way:
while (!list_head.compare_exchange_weak(newNode->next, newNode)) {}
// (with newNode->next updated accordingly if some other thread just appended another node)
} int main()
{
// spawn 10 threads to fill the linked list:
vector<thread> threads;
for (int i = ; i<; ++i)
threads.push_back(thread(append, i));
for (auto& th : threads) th.join();
// print contents:
for (Node* it = list_head; it != nullptr; it = it->next)
cout << ' ' << it->value;
std::cout << '\n';
// cleanup:
Node* it; while (it = list_head) { list_head = it->next; delete it; } system("pause");
return ;
}
http://blog.csdn.net/liuxuejiang158blog/article/details/17413149
atomic原子操作的更多相关文章
- 并发之java.util.concurrent.atomic原子操作类包
15.JDK1.8的Java.util.concurrent.atomic包小结 14.Java中Atomic包的原理和分析 13.java.util.concurrent.atomic原子操作类包 ...
- 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 ...
- goalng-sync/atomic原子操作
目录 1.go已经提供了锁,为什么还需要atomic原子操作? 2.atomic原子操作为什么比mutex快? 3.CAS 4.互斥锁与原子操作区别 5.原子操作方法 5.1 atomic.AddIn ...
- atomic 原子操作
原子操作:操作仅由一个独立的CPU指令代表和完成.保证并发环境下原子操作的绝对安全 标准库代码包:sync/atomic atomic是最轻量级的锁,在一些场景下直接使用atomic包还是很有效的 C ...
- 深入理解Atomic原子操作和volatile非原子性
原子操作可以理解为: 一个数,很多线程去同时修改它,不加sync同步锁,就可以保证修改结果是正确的 Atomic正是采用了CAS算法,所以可以在多线程环境下安全地操作对象. volatile是Java ...
- 深入理解java:2.3.1. 并发编程concurrent包 之Atomic原子操作(循环CAS)
java中,可能有一些场景,操作非常简单,但是容易存在并发问题,比如i++, 此时,如果依赖锁机制,可能带来性能损耗等问题, 于是,如何更加简单的实现原子性操作,就成为java中需要面对的一个问题. ...
- atomic 原子操作的类
import java.util.concurrent.atomic.AtomicInteger; /** * 原子操作的类 atomic */ public class VolatileDemo { ...
- 并发之ATOMIC原子操作--Unsafe解析(三)
Atomic 类的原子操作是依赖java中的魔法类sun.misc.Unsafe来实现的,而这个类为我们提供了访问底层的机制,这种机制仅供java核心类库使用,而不应该被普通用户使用. 获取Unsaf ...
- 5.1 CUDA atomic原子操作
和许多多线程并行问题一样,CUDA也存在互斥访问的问题,即当一个线程改变变量X,而另外一个线程在读取变量X的值,执行原子操作类似于有一个自旋锁,只有等X的变量在改变完成之后,才能执行读操作,这样可以保 ...
随机推荐
- 事件冒泡 & 阻止事件冒泡
事件冒泡 : 当一个元素接收到事件的时候,会把他接收到的所有传播给他的父级,一直到顶层window.事件冒泡机制 阻止冒泡 : 当前要阻止冒泡的事件函数中调用 event.cancelBubble = ...
- 加快create-react-app的方法
npm config get registry 查看npm源,默认源是 https://registry.npmjs.org/ npm config set registry https://regi ...
- sqlserver 分页问题
1.top 主要是在sql server 2000中使用,效率较差 2.row_number函数 这种方法是sql server 2005以后,支持了row_number函数后,才开始使用的. dec ...
- PyTorch的十七个损失函数
本文截取自<PyTorch 模型训练实用教程>,获取全文pdf请点击: tensor-yu/PyTorch_Tutorialgithub.com 版权声明:本文为博主原创文章,转载请附上 ...
- java对比IO和NIO的文件读写性能测试
1. NIO采用更接近操作系统执行IO的方式:通道和缓存器:顾名思义,数据源的数据由缓存器通过通道进行传输. 2. 在JDK5之后,原始IO系统底层用NIO进行了优化,这可以通过sun公布的源码中找到 ...
- 4. COLLATION_CHARACTER_SET_APPLICABILITY
4. COLLATION_CHARACTER_SET_APPLICABILITY 表COLLATION_CHARACTER_SET_APPLICABILITY表示哪种字符集适用于哪种排序规则. INF ...
- 【JDBC】java连接MySQL数据库步骤
java连接数据库步骤 1. 加载驱动 Class.forName("com.mysql.java.Driver"); 或: registerDriver(new com.mysq ...
- Canvas标签
1.Canvas标签: HTML5<canvas>元素用于图形的绘制,通过脚本(通常是javascript)来完成<canvas>标签只是图形容器,必须使用脚本来绘制图形.你可 ...
- (二)Robto Framewoek使用自己的python库
有时候找不到合适的库来完成自动化工作,则需要使用自己定义的python库.本文简单描述自建python库,以及在robotframework中的使用方法. 新建库目录 在C:\Python27\Lib ...
- Web安全解决方案
什么是 .NET Framework 安全性? .NET Framework 提供了用户和代码安全模型,允许对用户和代码可以执行的操作进行限制.要对基于角色的安全性和代码访问安全性进行编程,可以从 S ...