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原子操作的更多相关文章

  1. 并发之java.util.concurrent.atomic原子操作类包

    15.JDK1.8的Java.util.concurrent.atomic包小结 14.Java中Atomic包的原理和分析 13.java.util.concurrent.atomic原子操作类包 ...

  2. 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 ...

  3. goalng-sync/atomic原子操作

    目录 1.go已经提供了锁,为什么还需要atomic原子操作? 2.atomic原子操作为什么比mutex快? 3.CAS 4.互斥锁与原子操作区别 5.原子操作方法 5.1 atomic.AddIn ...

  4. atomic 原子操作

    原子操作:操作仅由一个独立的CPU指令代表和完成.保证并发环境下原子操作的绝对安全 标准库代码包:sync/atomic atomic是最轻量级的锁,在一些场景下直接使用atomic包还是很有效的 C ...

  5. 深入理解Atomic原子操作和volatile非原子性

    原子操作可以理解为: 一个数,很多线程去同时修改它,不加sync同步锁,就可以保证修改结果是正确的 Atomic正是采用了CAS算法,所以可以在多线程环境下安全地操作对象. volatile是Java ...

  6. 深入理解java:2.3.1. 并发编程concurrent包 之Atomic原子操作(循环CAS)

    java中,可能有一些场景,操作非常简单,但是容易存在并发问题,比如i++, 此时,如果依赖锁机制,可能带来性能损耗等问题, 于是,如何更加简单的实现原子性操作,就成为java中需要面对的一个问题. ...

  7. atomic 原子操作的类

    import java.util.concurrent.atomic.AtomicInteger; /** * 原子操作的类 atomic */ public class VolatileDemo { ...

  8. 并发之ATOMIC原子操作--Unsafe解析(三)

    Atomic 类的原子操作是依赖java中的魔法类sun.misc.Unsafe来实现的,而这个类为我们提供了访问底层的机制,这种机制仅供java核心类库使用,而不应该被普通用户使用. 获取Unsaf ...

  9. 5.1 CUDA atomic原子操作

    和许多多线程并行问题一样,CUDA也存在互斥访问的问题,即当一个线程改变变量X,而另外一个线程在读取变量X的值,执行原子操作类似于有一个自旋锁,只有等X的变量在改变完成之后,才能执行读操作,这样可以保 ...

随机推荐

  1. JavaScript-基础类型和运算符

    JavaScript-基础类型和运算符 P02.稍微了解 1.js代码需要编写到script标签中 <script type="text/javascript"> 此处 ...

  2. win10使用自带虚拟机没有Hyper-V场景

    开始咯~ 1.打开控制面板-程序和功能-启用或关闭Windows功能 2.发现下面并没有Hyper-v 真难受~~~   然后百度了一下原来是家庭版的win10没有.那就只能往下面看咯~ 3.在桌面添 ...

  3. uva1380 A Scheduling Problem

    按紫书来注意这道题的题目给了很大的方便,就相当于验证k是不是答案,不是的话就是k+1 #include<iostream> #include<string> #include& ...

  4. k8s集群部署之环境介绍与etcd数据库集群部署

    角色 IP 组件 配置 master-1 192.168.10.11 kube-apiserver kube-controller-manager kube-scheduler etcd 2c 2g ...

  5. log4j.xml 精选的log4j.xml文档,比较详细,网上的版本很多,这个版本相对而言比较完整

    <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE log4j:configuration PUB ...

  6. JS第三方中间件的延伸

    js中间件 当我们在编写业务代码时候,我们无法避免有些业务逻辑复杂而导致业务代码写得又长又乱,如果再加上时间紧凑情况下写出来的代码估计会更让人抓狂.以至于我们一直在寻求更好的架构设计和更好的代码设计, ...

  7. windows cmd 模仿电影黑客

    1.win+R 2.输入cmd 3.按F11进入全屏 4.color a 改变颜色为绿色(可能看起来秀一点) 5.dir/s 查看所有文件,就跑起来了,看起来很酷,但是在懂得人眼里,没什么的(所以只能 ...

  8. 使用VS自带WCF测试客户端

    打开VS自带WCF测试客户端 打开VS2015 开发人员命令提示 输入:wcftestclient,回车 提取wcftestclient 当然,可以看到VS2015 开发人员命令提示知道,当前路径在C ...

  9. git命令使用(一)

    作为程序员怎么能不了解git命令呢,但是由于本人不常用到git命令,现在的软件上也都一体化了,能够简化命令,直接运行都可以了,完全能够去实现git上的命令,导致输入git命令完全不会,git命令能够让 ...

  10. 条款3:尽可能使用const(use const whenever possible)

    1.只要这(某值保持不变)是事实,就应该确实说出来,这样可以获得编译器的协助,确保这条约束不被违反. 2.keyword const 有很多种用法,但都简单易用. 2.1classes 外部修饰glo ...