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. How to Slove MB SD C4 Cannot Access OBD2 Port

    When using china clone mb sd connect compact 4 Multiplexer, it could not link to the car computer, M ...

  2. MySQL-06 数据备份和恢复

    学习目标 数据备份 数据恢复 数据库迁移 导入和导出 数据备份 系统意外崩溃或者服务器硬件损坏都有可能导致数据库丢失,因此生产环境中数据备份非常重要. MySQLdump命令备份 该命令可以将数据库备 ...

  3. C#中byte类型运算

    首先看下面一段代码 byte x = 1; byte y = 2; byte z = x + y; Console.WriteLine(z); 可能很多人会说显示结果是3. 其实,这段代码无法运行,因 ...

  4. WebSocket 学习笔记

    WebSocket 学习笔记 来自我的博客 因为项目原因需要用到双工通信,所以比较详细的学习了一下浏览器端支持的 WebSocket. 并记录一些遇到的问题. 简介 WebSocket 一般是指浏览器 ...

  5. Python自动化测试框架——生成测试报告

    如何才能让用例自动运行完之后,生成一张直观可看易懂的测试报告呢? 小编使用的是unittest的一个扩展HTMLTestRunner 环境准备 使用之前,我们需要下载HTMLTestRunner.py ...

  6. linux配置网桥

    实现环境: centos7   Linux devstack01 3.10.0-693.el7.x86_64 1.创建br配置文件,ifcfg-br2 cp ifcfg-br0 ifcfg-br2 2 ...

  7. 第六天,字典Dictionary

    字典(Dictionary)在Python中是一种可变的容器模型,它是通过一组键(key)值(value)对组成,这种结构类型通常也被称为映射,或者叫关联数组,也有叫哈希表的.每个key-value之 ...

  8. solr 分析器

    源https://www.w3cschool.cn/solr_doc Solr 分析器被指定为 schema.xml 配置文件中的<fieldType>元素的子元素(在与 solrconf ...

  9. Cable master 求电缆的最大长度(二分法)

    Description Inhabitants of the Wonderland have decided to hold a regional programming contest. The J ...

  10. SHELL十三问[转载自CU论坛]

    原文地址:http://bbs.chinaunix.net/thread-218853-1-1.html 一.为什么称作shell? http://bbs.chinaunix.net/viewthr ...