1. 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 (不用锁实现线程互斥)的更多相关文章

  1. C++11 并发指南六(atomic 类型详解三 std::atomic (续))

    C++11 并发指南六( <atomic> 类型详解二 std::atomic ) 介绍了基本的原子类型 std::atomic 的用法,本节我会给大家介绍C++11 标准库中的 std: ...

  2. C++11 并发指南六( <atomic> 类型详解二 std::atomic )

    C++11 并发指南六(atomic 类型详解一 atomic_flag 介绍)  一文介绍了 C++11 中最简单的原子类型 std::atomic_flag,但是 std::atomic_flag ...

  3. 第31课 std::atomic原子变量

    一. std::atomic_flag和std::atomic (一)std::atomic_flag 1. std::atomic_flag是一个bool类型的原子变量,它有两个状态set和clea ...

  4. std::atomic和std::mutex区别

    ​ ​std::atomic介绍​ ​模板类std::atomic是C++11提供的原子操作类型,头文件 #include<atomic>.​在多线程调用下,利用std::atomic可实 ...

  5. 用C++11的std::async代替线程的创建

    c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int n); std::thread t(f, n + 1); t.join(); 但是线程毕竟是属于比 ...

  6. C++11多线程std::thread的简单使用

    在cocos2dx 2.0时代,我们使用的是pthread库,是一套用户级线程库,被广泛地使用在跨平台应用上.但在cocos2dx 3.0中并未发现有pthread的支持文件,原来c++11中已经拥有 ...

  7. C++11 使用 std::async创建异步程序

    c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int n); std::thread t(f, n + 1); t.join(); 但是线程毕竟是属于比 ...

  8. (原创)用C++11的std::async代替线程的创建

    c++11中增加了线程,使得我们可以非常方便的创建线程,它的基本用法是这样的: void f(int n); std::thread t(f, n + ); t.join(); 但是线程毕竟是属于比较 ...

  9. Cocos2dx 3.0 过渡篇(二十七)C++11多线程std::thread的简单使用(下)

    本篇接上篇继续讲:上篇传送门:http://blog.csdn.net/star530/article/details/24186783 简单的东西我都说的几乎相同了,想挖点深的差点把自己给填进去. ...

随机推荐

  1. MVC后台获取数据和插入数据的三种方式【二】

    MVC模式下,从前端获取数据返回后台,总共有三种形式.下面的代码示例将演示如何将数据返回到后端. 一.首先我们看看表单代码,注意input标签中name的值. <html> <hea ...

  2. Eclipse+maven 构建第一个简单的springmvc项目

    先给出项目的目录: 在eclipse下使用maven构建第一个springmvc项目步骤如下: 1.创建maven project(此处默认你已了解maven),此处需要注意以下两点 2.创建完毕后会 ...

  3. Python 创建和使用类

    python创建和使用类的方法如下 # class Dog(): # def __init__(self,name,age): # self.name=name # self.age=age # # ...

  4. C#中 == 与 Equals的简单理解

    using System; using System.Collections.Generic; using System.Collections; using System.IO; using Sys ...

  5. 如何获取select选中的值

    一:JavaScript原生的方法 1:拿到select对象: var myselect=document.getElementById(“test”); 2.拿到选中项的索引: var index= ...

  6. JFinal3.0 sql管理与动态生成

    原文: 本节学习目标主要是使用JFinal中自带的Template Engin来实现对sql的管理.JFinal中为sql管理提供了3个指令#sql.#para.#namespace,来增强sql功能 ...

  7. 基因/转录本/任意特征 表达定量工具之featureCounts使用方法 | 参数详解

    featureCounts真的很厉害. 常见的参数(没什么好说的,毕竟是固定的): -a -o input_file1 -F -t -g -Q -T 关键是以下几个参数怎么设置: -f # Perfo ...

  8. hdu-6194 string string string 后缀数组 出现恰好K次的串的数量

    最少出现K次我们可以用Height数组的lcp来得出,而恰好出现K次,我们只要除去最少出现K+1次的lcp即可. #include <cstdio> #include <cstrin ...

  9. Confluence 6 可以自定义的元素

    色彩配色方案允许你对 UI 中的元素色彩进行编辑,包括顶部条,标签页和背景色. 有一些下面的 UI 元素被用在特定的主题中,配色方案的修改可能不会对这些元素有效. 顶部条(Top Bar)—— 顶部导 ...

  10. ModelViewSet 视图集 实现接口

    一.创建项目 1.创建 项目 : django-admin startprojet drf 2. 创建 两个app   ------ app1 ,book python manage.py start ...