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的变量在改变完成之后,才能执行读操作,这样可以保 ...
随机推荐
- DROP VIEW - 删除一个视图
SYNOPSIS DROP VIEW name [, ...] [ CASCADE | RESTRICT ] DESCRIPTION 描述 DROP VIEW 从数据库中删除一个现存的视图. 执行这条 ...
- dirname, basename - 分析路径成员
总览 (SYNOPSIS) #include <libgen.h> char *dirname(char *path); char *basename(char *path); 描述 (D ...
- python django项目断点调试
- PHP07 函数
学习要点 函数的定义 自定义函数 函数的工作原理和结构化编程 PHP变量范围 声明及应用各种形式的PHP函数 递归函数 使用自定义函数库 匿名函数和闭包 常用PHP系统函数 PHP7函数新特性 函数的 ...
- IOS学习笔记37——ViewController生命周期详解
在我之前的学习笔记中讨论过ViewController,过了这么久,对它也有了新的认识和体会,ViewController是我们在开发过程中碰到最多的朋友,今天就来好好认识一下它.ViewContro ...
- Linux下安装Redis5.0.2
1.下载redis 地址 http://download.redis.io/releases/redis-5.0.2.tar.gz 2.解压tar -zxf redis-5.0.2.tar.gz 3. ...
- gcc编译详解
GCC(GNU Compiler Collection,GNU编译器套件),是由 GNU 开发的编程语言编译器.它是以GPL许可证所发行的自由软件,也是 GNU计划的关键部分.GCC原本作为GNU操作 ...
- 对于easyui $.messager.alert和 $.messager.confirm 不同浏览器中位置控制
$.messager.confirm({ title: '种子购买', msg: '确定购买这个'+seedName+'的种子嘛?', top:, fn: function (r) { if (r){ ...
- centos7.4下搭建JDK+Tomcat+Nginx+Mysql+redis+Mongodb+maven+Git+Jenkins
先干两件大事!先干两件大事!先干两件大事! 1.关闭selinux [root@mycentos ~]# vi /etc/selinux/config SELINUX=disabled 2.关闭防火墙 ...
- 关联及web_reg_save_param
一.什么是关联 关联(correlation):脚本回放过程中,客户端发出请求,通过关联函数所定义的左右边界值(也就是关联规则),在服务器所响应的内容中查 找,得到相应的值,已变量的形式替换录制时的静 ...