【C++入门到精通】 原子性操作库(atomic) C++11 [ C++入门 ]

在这里插入图片描述

阅读导航

  • 引言
  • 一、原子性操作库简介
  • 二、原子变量
    • 1. 原子类型
    • 2. 原子类型函数
    • 3. 使用示例
  • 三、总结
  • 温馨提示

引言

当谈及并发编程时,确保数据的安全性和一致性是至关重要的。在C++11中引入的原子性操作库(atomic)为我们提供了一种有效且可靠的方式来处理多线程环境下的数据共享与同步问题。原子操作是不可分割的操作,它们可以确保在多线程环境中对共享数据的读写操作是原子的,即不会被其他线程中断或干扰。

本文将继续为大家介绍C++11中的一些重要特性,包括原子性操作库(atomic),这些特性能够帮助我们更好地管理多线程程序,提高程序的性能和稳定性。

一、原子性操作库简介

原子性操作库(atomic)是C++11中新增的标准库,它提供了一种线程安全的方式来访问和修改共享变量,避免了数据竞争的问题。在多线程程序中,如果多个线程同时对同一个变量进行读写操作,就可能会导致数据不一致的问题。原子性操作库通过使用原子操作来保证多个线程同时访问同一个变量时的正确性。

⭕原子性操作库的官方文档

在这里插入图片描述

⭕在原子性操作库中,每个原子变量都有以下几个特点:

  1. 原子变量的读写操作是原子的,即不会被其他线程中断。
  2. 原子变量的值可以被多个线程同时访问和修改。
  3. 原子变量的修改操作是按照一定顺序进行的,保证了多个线程对同一个变量进行操作时的正确性。

原子性操作库中提供了一系列的原子操作函数,包括load、store、exchange、compare_exchange等。load函数用于读取原子变量的值,store函数用于设置原子变量的值,exchange函数用于交换原子变量的值,而compare_exchange函数用于比较并交换原子变量的值。后面我会详细介绍

二、原子变量

原子性操作库(atomic)提供了多种类型的原子变量,包括boolcharshortintlonglong long等基本数据类型,以及intmax_tuintmax_tintptr_t等扩展类型。每个原子变量都有对应的原子类型,比如atomic_boolatomic_charatomic_int等。在使用时,我们需要根据实际的需求选择合适的原子类型和原子变量。

1. 原子类型

下面是原子性操作库中支持的一些原子类型:

原子类型描述
atomic_bool原子布尔型,只能存储true或false。
atomic_char原子字符型,相当于char类型。
atomic_uchar原子无符号字符型,相当于unsigned char类型。
atomic_schar原子有符号字符型,相当于signed char类型。
atomic_short原子短整型,相当于short类型。
atomic_ushort原子无符号短整型,相当于unsigned short类型。
atomic_int原子整型,相当于int类型。
atomic_uint原子无符号整型,相当于unsigned int类型。
atomic_long原子长整型,相当于long类型。
atomic_ulong原子无符号长整型,相当于unsigned long类型。
atomic_llong原子长长整型,相当于long long类型。
atomic_ullong原子无符号长长整型,相当于unsigned long long类型。
atomic_wchar_t原子宽字符型,相当于wchar_t类型。
atomic_char16_t原子16位字符型,相当于char16_t类型。
atomic_char32_t原子32位字符型,相当于char32_t类型。
atomic_intmax_t原子最大宽度整数类型,对应<inttypes.h>中的intmax_t类型。
atomic_uintmax_t原子最大宽度无符号整数类型,对应<inttypes.h>中的uintmax_t类型。
atomic_intptr_t原子指针宽度整数类型,对应<stddef.h>中的intptr_t类型。
atomic_uintptr_t原子指针宽度无符号整数类型,对应<stddef.h>中的uintptr_t类型。
atomic_size_t原子size_t类型,用于表示对象的大小。
atomic_ptrdiff_t原子ptrdiff_t类型,用于表示两个指针之间的距离。

2. 原子类型函数

🚨注意原子类型和原子操作函数需要包含 <atomic> 头文件才能使用

下面是常用的原子类型函数:

函数描述
load()原子读取操作,用于获取原子变量的当前值。
store()原子写入操作,用于设置原子变量的值。
exchange()原子交换操作,用于交换原子变量的值,并返回原始值。
fetch_add()原子加法操作,用于增加原子变量的值,并返回原始值。
fetch_sub()原子减法操作,用于减少原子变量的值,并返回原始值。
fetch_and()原子按位与操作,用于按位与原子变量的值,并返回原始值。
fetch_or()原子按位或操作,用于按位或原子变量的值,并返回原始值。
fetch_xor()原子按位异或操作,用于按位异或原子变量的值,并返回原始值。
fetch_min()原子最小值操作,将原子变量与给定值比较,并将较小的值存储在原子变量中。返回原始值。
fetch_max()原子最大值操作,将原子变量与给定值比较,并将较大的值存储在原子变量中。返回原始值。
fetch_mul()原子乘法操作,将原子变量与给定值相乘,并将结果存储在原子变量中。返回原始值。
fetch_div()原子除法操作,将原子变量与给定值相除,并将结果存储在原子变量中。返回原始值。
fetch_and_not()原子按位与非操作,对原子变量进行按位与非运算,并将结果存储在原子变量中。返回原始值。
fetch_negate()原子取反操作,对原子变量进行取反运算,并将结果存储在原子变量中。返回原始值。
fetch_bitwise_and()原子按位与操作,将原子变量与给定值进行按位与运算,并将结果存储在原子变量中。返回原始值。
fetch_bitwise_or()原子按位或操作,将原子变量与给定值进行按位或运算,并将结果存储在原子变量中。返回原始值。
fetch_bitwise_xor()原子按位异或操作,将原子变量与给定值进行按位异或运算,并将结果存储在原子变量中。返回原始值。

🚨注意以上函数只是原子类型库中的一部分函数,还有其他函数可用于更复杂的操作,具体取决于你的需求。

3. 使用示例

下面是一个使用原子性操作库的样例,展示了如何创建和操作原子变量:

#include <atomic>
#include <iostream>int main() {std::atomic_int counter(0); // 创建一个原子整型变量并初始化为0counter++; // 原子操作:递增counter的值int value = counter.load(); // 原子操作:读取counter的值std::cout << "Counter value: " << value << std::endl;counter.store(10); // 原子操作:将counter的值设置为10bool exchanged = counter.compare_exchange_weak(value, 5); // 原子操作:比较并交换counter的值if (exchanged) {std::cout << "Value exchanged successfully!" << std::endl;} else {std::cout << "Value exchange failed!" << std::endl;}return 0;
}

在这个样例中,我们首先使用std::atomic_int创建一个原子整型变量counter并将其初始化为0。然后,我们演示了几种原子操作:

  • counter++:原子递增操作,使用++操作符自增counter的值。
  • counter.load():原子读取操作,读取counter的当前值。
  • counter.store(10):原子写入操作,将counter的值设置为10。
  • counter.compare_exchange_weak(value, 5):原子比较并交换操作,比较counter的值与value是否相等,如果相等则将counter的值设为5,并返回交换是否成功的结果。

以上是原子性操作库的简单使用样例,通过使用原子类型和原子操作,我们可以确保多线程环境下对共享变量的安全访问和修改

三、总结

通过学习本文所介绍的内容,我们可以更好地理解并发编程中的原子性操作库的概念和作用。原子操作库提供了一种可靠、高效的方式来处理多线程环境下的数据共享和同步问题。在实际应用中,我们需要根据具体场景选择适当的原子类型和操作函数,并合理设置内存顺序,以平衡性能和正确性需求。

综上所述,原子性操作库是C++11中一个强大而重要的工具,它为我们在多线程编程中处理数据共享与同步提供了有效的解决方案。通过合理运用原子类型和操作函数,我们能够编写出更加健壮和可靠的多线程应用程序。希望本文对读者在学习并发编程中的原子性操作库有所帮助。

温馨提示

感谢您对博主文章的关注与支持!另外,我计划在未来的更新中持续探讨与本文相关的内容,会为您带来更多关于C++以及编程技术问题的深入解析、应用案例和趣味玩法等。请继续关注博主的更新,不要错过任何精彩内容!

再次感谢您的支持和关注。期待与您建立更紧密的互动,共同探索C++、算法和编程的奥秘。祝您生活愉快,排便顺畅!
在这里插入图片描述

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

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

相关文章

2004年AMC8数学竞赛中英文真题典型考题、考点分析和答案解析

今天距离2024年的AMC8美国数学竞赛举办已不足一个月了&#xff0c;赶紧利用周末的时间刷刷真题&#xff0c;查漏补缺吧&#xff01;如果您有任何关于AMC8比赛的任何问题都可以问我&#xff0c;关于题目的解析也可以交流。 今天六分成长继续和您一起&#xff0c;从历年的真题中来…

Ubuntu 常用命令之 man 命令用法介绍

&#x1f4d1;Linux/Ubuntu 常用命令归类整理 man命令在Ubuntu系统中是一个非常重要的命令&#xff0c;它用于查看系统的手册页。手册页是Linux和Unix系统中的一种在线文档&#xff0c;用于描述系统中的命令、函数、配置文件等的详细信息。 man命令的基本格式是 man [选项] …

FPC柔性线路板使用UV胶水的优势有哪些?

UV胶水在FPC柔性线路板的装配中具有明显的优势&#xff1a; 快速固化 UV胶水在紫外线照射后10秒左右迅速固化&#xff0c;因此它能够在短时间内完成连接。这非常有助于实际工业作业中提高生产效率&#xff0c;特别是在需要大批量生产的情况下。 精确控制固化时间 UV胶水的固…

前端:NPM的介绍和使用

一、NPM的介绍 NPM是Node.js的包管理器&#xff0c;用于管理Node.js的包NPM提供了方便的方式来安装、管理和分享Node.js的包 二、NPM的使用 1. 安装NPM 要使用NPM&#xff0c;首先需要安装Node.js。安装完成后&#xff0c;可以在命令行中运行以下命令来检查Node.js和NPM是否…

DeamonSet详解

目录 1.1 何为DaemonSet 1.2 DaemonSet 的 API 对象的定义 1.3 DaemonSet实践 1.3.1 创建 DaemonSet 对象 1.3.2 查看 DaemonSet 对象 1.3.3 DaemonSet 版本管理 1.3.4 DaemonSet 的容器镜像版本到 v2.2.0 1.1 何为DaemonSet 介绍DaemonSet我们先来思考一个问题&#x…

pip 常用指令 pip cache 命令用法介绍

&#x1f4d1;pip 常用命令归类整理 pip cache 是一个用于管理pip缓存的命令。pip是Python的包管理器&#xff0c;用于安装和管理Python包。当你使用pip安装一个包时&#xff0c;pip会首先在其缓存中查找该包。如果在缓存中找到&#xff0c;pip将从缓存中安装该包&#xff0c;…

MariaDB 主-从

一、MariaDB 主-从 同步配置 基于一台服务器的数据复制,故得名单机热备,主-备 Active-Standby 主-备方式,即指的是一台服务器处于某种业务的激活状态(即Active状态),另一台服务器处于该业务的备用状态(即Standby状态),主数据库数据更新后,备份服务器同步数据只本机 1.安装Ma…

【ARM 安全系列介绍 3.4 -- 安全证书介绍】

文章目录 安全证书安全证书的主要组成部分安全证书的应用场景证书使用举例 证书格式PEM (Privacy Enhanced Mail)DER (Distinguished Encoding Rules)PKCS#7/P7B (Public Key Cryptography Standards #7)PKCS#12/PFX (Public Key Cryptography Standards #12)P7B 和 PFX/P12 的…

P1019 [NOIP2000 提高组] 单词接龙

题目链接 P1019 [NOIP2000 提高组] 单词接龙 细节 题目中描述的在两个单词相连时&#xff0c;其重合部分合为一部分具有一定的误导性&#xff0c;对于字符串 b e e bee bee 和 e e d eed eed &#xff0c;合并之后的字符串为 b e e e d beeed beeed &#xff0c;只有中间…

Vue 在同一个项目中,判断pc端和移动端,显示不同风格的页面(附pc端移动端显示效果图)

实现思路 1、修改index.html页面的meta 2、增加pc端移动端的判断 3、设置路由&#xff0c;根据不同的端&#xff0c;调用各自的路由&#xff0c;显示不同的页面 index.html 修改如下 <meta name"viewport" content"widthdevice-width,initial-scale1.0,minim…

51单片机模数转换ADC原理与代码一

51单片机模数转换ADC原理与代码一 1.概述 这篇文章是模数转换的入门文章&#xff0c;这篇文章主要介绍模数的概念、原理、核心指标、专业术语&#xff0c;以及一个模数转换的实例代码实现检测电位器的数值变化。 2.ADC介绍 2.1.ADC概念 ADC(Analog-to-Digital Converter)是…

tomcat和nginx自定义404错误页面

nginx 编辑nginx配置文件 vim /www/server/nginx/nginx.conf server{listen 80;error_page 404 /404.html;location /404.html{root /home/liu/html/error-html;} }在家目录下创建一个html/error-html目录&#xff0c;用于存放错误页面 在error-html目录下创建404.html&a…

node.js mongoose index(索引)

目录 简介 索引类型 单索引 复合索引 文本索引 简介 在 Mongoose 中&#xff0c;索引&#xff08;Index&#xff09;是一种用于提高查询性能的数据结构&#xff0c;它可以加速对数据库中文档的检索操作 索引类型 单索引、复合索引、文本索引、多键索引、哈希索引、地理…

面试建议篇(持续更新....)

不要把面试当作回答问题的过程&#xff0c;而是一个交流和沟通过程。 和面试官交流比重是1:3。 面对毫不知情的问题&#xff1a;直言没有遇到过&#xff0c;然后说出自己的理解。解决问题的思路比标准答案更重要&#xff1b;真诚是最核心的加分项。 当我遇到问题时&#xff0c;…

ubuntu20 安装缺失的字体

在/usr/share/fonts创建文件夹winfonts sudo mkdir winfonts 下载缺失的字体后&#xff0c;复制命令到对应的文件夹。 刷新字体库 sudo mkfontscale sudo mkfontdir sudo fc-cache

c# opencv 获取多边形中心点

在C#中使用OpenCV获取多边形的中心点&#xff0c;可以按照以下步骤进行&#xff1a; 首先&#xff0c;你需要找到图像中的轮廓。这可以通过FindContours方法实现&#xff1a; using OpenCvSharp;Mat src new Mat("your_image_path", ImreadModes.Grayscale); Mat …

十二、W5100S/W5500+RP2040之MicroPython开发<MQTT旧版OneNET示例>

文章目录 1. 前言2. 平台操作流程3. WIZnet以太网芯片4. 示例讲解以及使用4.1 程序流程图4.2 测试准备4.3 连接方式4.4 相关代码4.5 烧录验证 5. 注意事项6. 相关链接 1. 前言 在这个智能硬件和物联网时代&#xff0c;MicroPython和树莓派PICO正以其独特的优势引领着嵌入式开发…

人工智能_机器学习070_SVM支持向量机_软间隔及优化_硬间隔_衡量间隔软度_引入松弛变量_理解隔离参数---人工智能工作笔记0110

我们继续说,之前说的C是什么意思? 我们在这个软间隔优化中就可以引出C 可以看到之前我们讨论的问题,都是基于样本点的,完全的线性可分的问题,我们称为硬间隔 可以看到这种,一分就可以,分开,简单分割就可以分开的数据,我们称之为硬间隔 但是可以看到上面这种情况,无论怎么分,都…

智能硬件(6)之通用引脚(GPIO)

小编带领大家学习的四大开源硬件和智能模块&#xff0c;他们之间是如何通信的&#xff0c;主控芯片是如何控制智能模块&#xff0c;做某些事情呢&#xff1f;有没有小朋友发起疑问呢&#xff1f; 这里&#xff0c;涉及到了特别重要的知识点&#xff0c;就是通用引脚&#xff0c…

Apache Flink 进阶教程(六):Flink 作业执行深度解析

目录 前言 Flink 四层转化流程 Program 到 StreamGraph 的转化 StreamGraph 到 JobGraph 的转化 为什么要为每个 operator 生成 hash 值&#xff1f; 每个 operator 是怎样生成 hash 值的&#xff1f; JobGraph 到 ExexcutionGraph 以及物理执行计划 Flink Job 执行流程…