C++11之atomic原子操作

news2024/9/29 1:18:00

atomic介绍

多线程间是通过互斥锁与条件变量来保证共享数据的同步的,互斥锁主要是针对过程加锁来实现对共享资源的排他性访问。很多时候,对共享资源的访问主要是对某一数据结构的读写操作,如果数据结构本身就带有排他性访问的特性,也就相当于该数据结构自带一个细粒度的锁,对该数据结构的并发访问就能更加简单高效,这就是C++11提供的原子数据类型< atomic >

 所谓的原子操作,取的就是“原子是最小的、不可分割的最小个体”的意义,它表示在多个线程访问同一个全局资源的时候,能够确保所有其他的线程都不在同一时间内访问相同的资源。也就是他确保了在同一时刻只有唯一的线程对这个资源进行访问。这有点类似互斥对象对共享资源的访问的保护,但是原子操作更加接近底层,因而效率更高。

原子操作:顾名思义就是不可分割的操作,该操作只存在未开始和已完  成两种状态,不存在中间状态;

原子类型:原子库中定义的数据类型,对这些类型的所有操作都是原子的,包括通过原子类模板std::atomic< T >实例化的数据类型,也都是支持原子操作的。

原子库atomic支持的原子操作

原子库< atomic >中提供了一些基本原子类型,也可以通过原子类模板实例化一个原子对象,下面列出一些基本原子类型及相应的特化模板如下:

 对原子类型的访问,最主要的就是读和写,但原子库提供的对应原子操作是load()与store(val)。原子类型支持的原子操作如下:

原子操作中的内存访问模型

原子操作保证了对数据的访问只有未开始和已完成两种状态,不会访问到中间状态,但我们访问数据一般是需要特定顺序的,比如想读取写入后的最新数据,原子操作函数是支持控制读写顺序的,即带有一个数据同步内存模型参数std::memory_order,用于对同一时间的读写操作进行排序。C++11定义的6种类型如下:

//这里枚举这六种
typedef enum memory_order {
    memory_order_relaxed, 
    memory_order_consume, 
    memory_order_acquire, 
    memory_order_release,
    memory_order_acq_rel,
    memory_order_seq_cst 
} memory_order;
  • memory_order_seq_cst: 顺序一致性模型,这是C++11原子操作的默认模型;大概行为为对每一个变量都进行Release-Acquire操作,当然这也是一个最慢的同步模型;
  • memory_order_relaxed: 宽松操作,没有同步或顺序制约,仅对此操作要求原子性;
  • memory_order_release & memory_order_acquire: 两个线程A&B,A线程Release后,B线程Acquire能保证一定读到的是最新被修改过的值;这种模型更强大的地方在于它能保证发生在A-Release前的所有写操作,在B-Acquire后都能读到最新值;
  • memory_order_release & memory_order_consume: 上一个模型的同步是针对所有对象的,这种模型只针对依赖于该操作涉及的对象:比如这个操作发生在变量a上,而s = a + b; 那s依赖于a,但b不依赖于a; 当然这里也有循环依赖的问题,例如:t = s + 1,因为s依赖于a,那t其实也是依赖于a的;
/*使用原子操作来控制线程顺序,实现了一个类似于互斥锁这么一个概念*/
#include 
#include 
#include 
using namespace std;

int g_value(0);
atomic g_data_ready(false);

void read_thread()
{
    while (true)
    {
        while (!g_data_ready.load());//用于控制进入
        cout << g_value << endl;
        g_data_ready = false;
    }
}

void write_thread()
{
    while (true)
    {
        while (g_data_ready.load());//用于控制进入
        Sleep(1000);
        g_value++;
        g_data_ready = true;
    }
}

int main()
{
    thread th(read_thread);
    th.detach();
    thread th2(write_thread);
    th2.detach();
    char a;
    while (cin >> a);
    return 0;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/586687.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python中的等待:理解和优化

Python中的等待&#xff1a;理解和优化 Python是一种强大的编程语言&#xff0c;在构建各种应用程序时很常用。但是&#xff0c;随着应用程序越来越复杂&#xff0c;需要等待一些操作时&#xff0c;Python中的等待传统上会导致性能下降。在这篇文章中&#xff0c;我们将深入了…

可持续能源技术改变世界

文章目录 一、你在工作或生活中接触过可持续能源技术吗&#xff1f;可以分享下你的经历与看法。二、你认为可持续能源技术的优势和挑战有哪些&#xff1f;三、你了解过可持续能源技术的应用现状吗&#xff1f;四、对于可持续能源技术真的否改变世界这个问题你怎么看&#xff1f…

ifconfig工具与驱动交互解析(ioctl)

Linux ifconfig&#xff08;network interfaces configuring&#xff09; Linux ifconfig命令用于显示或设置网络设备。ifconfig可设置网络设备的状态&#xff0c;或是显示目前的设置。同netstat一样&#xff0c;ifconfig源码也位于net-tools中。源码位于net-tools工具包中&am…

《消息队列高手课》课程笔记(七)

如何使用异步设计提升系统性能&#xff1f; 异步设计如何提升系统性能&#xff1f; 假设我们要实现一个转账的微服务 Transfer(accountFrom, accountTo, amount)&#xff0c;这个服务有三个参数&#xff1a;分别是转出账户、转入账户和转账金额。 这个例子的实现过程中&…

chatgpt赋能python:Python中如何反转字符串:三种简单方法

Python中如何反转字符串&#xff1a;三种简单方法 当我们在处理字符串时&#xff0c;有时需要将其反向排列。在Python中&#xff0c;这可以通过以下三种简单方法实现&#xff1a; 1. 使用内置的切片方法 在Python中&#xff0c;可以使用字符串的切片方法将其反转。这种方法非…

(浙大陈越版)数据结构 第三章 树(上) 3.4 小白专场:树的同构(PTA编程题讲解)

题意理解和二叉树表示 给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换变成T2&#xff0c;则称两棵树是“同构”的。 eg1&#xff1a;现请你判断如下两棵树&#xff08;左侧为T1&#xff0c;右侧为T2&#xff09;是否为同构树&#xff1f; 显然T1可以通过有限次左右孩子…

REST风格 -- SpringMVC入门保姆级教程(四)

文章目录 前言四、REST风格1.了解REST风格2.REST风格写法一般步骤3.REST风格快速开发4.REST风格中的注解5. 案例&#xff1a;基于REST风格页面数据交互 总结 前言 为了巩固所学的知识&#xff0c;作者尝试着开始发布一些学习笔记类的博客&#xff0c;方便日后回顾。当然&#…

Redis高级篇 - 分布式缓存

分布式缓存 基于Redis集群解决单机Redis存在的问题 单机的Redis存在四大问题&#xff1a; 1.Redis持久化 Redis有两种持久化方案&#xff1a; RDB持久化AOF持久化 1.1.RDB持久化 RDB全称Redis Database Backup file&#xff08;Redis数据备份文件&#xff09;&#xff0c…

iPad触屏笔哪个牌子好用?Apple Pencil的平替笔

从无纸化的广泛使用&#xff0c;电容笔成为无纸化中不可替代的一部分。但由于原装电容笔的昂贵&#xff0c;市面上的电容笔品牌众多&#xff0c;不知如何下手&#xff0c;今天给大家推荐几款好用又平价的Apple Pencil平替笔。顺便给不知道如何挑选电容笔的小伙伴科普一下电容笔…

车载网络测试 - CANCANFD - 基础篇_02

目录 七、与CAN总线相关的标准 1、ISO 11898,ISO16845 2、SAE J1939,ISO 11783,NMEA 2000,CANopen 3、ISO15765/ISO14229 4、ISO 17356/OSEK 5、CCP(CAN Calibration Protocol) 6、GMLAN,VWTP,FNOS,DCNet,MCNet 八、CAN总线的特点 九、CAN总线基本概念 七、与CAN总线相…

机器学习-4 决策树算法

决策树算法 算法概述分类算法与分类器决策树算法树模型决策树的原理决策树算法的关键决策树构造的基本思路 算法基本思想决策树的训练与测试三种经典的决策树生成算法基于信息增益的ID3算法基于信息增益率的C4.5算法C4.5算法C5.0算法 基于基尼系数的CART算法 算法流程算法关键问…

chatgpt赋能python:Python中的包

Python中的包 对于使用Python进行编程的开发者来说&#xff0c;包是一个非常重要的概念。包可以看作是一个包含了多个模块的文件夹&#xff0c;这些模块可以在代码中使用。通过使用Python中的包&#xff0c;开发者可以使代码更加模块化&#xff0c;提高代码的可维护性和可读性…

Emacs之git操作(一百零五)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

Apache Impala(1):Impala简介

1 Impala 基本介绍 impala 是 cloudera 提供的一款高效率的 sql 查询工具&#xff0c;提供实时的查询效果&#xff0c;官方测试性能比 hive 快 10 到 100 倍&#xff0c;其 sql 查询比 sparkSQL 还要更加快速&#xff0c;号称是当前大数据领域最快的查询 sql 工具&#xff0c…

小主机折腾记13

这个月折腾的事比较多&#xff0c;记个流水账 1.600g2mt加装wifi模块&#xff1b; 买了ngff转pcie的转接卡&#xff0c;发现竟然不能原生支持蓝牙&#xff0c;需要额外接一个4pin转9针usb的线&#xff0c;600g2mt是没有那种通用的usb9针口的…… 而内建蓝牙的转接卡网上也有卖&…

【项目】ROS下使用N100模块

本文主要记录如何使用WHEELTEC N100 模块。 之前的版本是CP2102串口芯片&#xff0c;而2022年5月之后的N100采用的是CH9102串口芯片。 一、修改串口号&#xff1a; 工具&#xff1a;链接&#xff1a;https://pan.baidu.com/s/13Pdq45_Z0ZRwuaNN0I84Cg 提取码&#xff1a;i6j…

《深入理解计算机系统(CSAPP)》第6章 存储器层次结构 - 学习笔记

写在前面的话&#xff1a;此系列文章为笔者学习CSAPP时的个人笔记&#xff0c;分享出来与大家学习交流&#xff0c;目录大体与《深入理解计算机系统》书本一致。因是初次预习时写的笔记&#xff0c;在复习回看时发现部分内容存在一些小问题&#xff0c;因时间紧张来不及再次整理…

【计算机网络详解】——应用层(学习笔记)

&#x1f4d6; 前言&#xff1a;应用层是计算机网络体系结构的最顶层&#xff0c;是设计和建立计算机网络的最终目的&#xff0c;也是计算机网络中发展最快的部分。在本文中&#xff0c;我们以一些经典的网络应用为例来学习有关网络应用的原理、协议和实现方面的知识。 目录 &a…

华为OD机试真题B卷 Java 实现【快速寻找某字符】,附详细解题思路

一、题目描述 给定一个一个目标值 target和一个 元素升序的无重复数字字符串 &#xff0c;写一个函数搜索 字符串 中的 target&#xff0c;如果目标值存在返回下标&#xff08;下标从 0 开始&#xff09;&#xff0c;否则返回 -1。 二、输入描述 第一行输入一个目标值target…

在Centos Stream 9上Docker的实操教程(三) - Docker容器数据卷

在Centos Stream 9上Docker的实操教程 - Docker容器数据卷 问题场景Docker容器数据卷简单介绍数据卷使用操作实例安装redis验证配置文件生效验证数据是否丢失 结语 问题场景 Docker容器我们可以理解就是微型的linux系统&#xff0c;在使用容器的时候自然会产生一系列数据文件&…