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

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

引言

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

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

一、原子性操作库简介

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

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

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

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

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

二、原子变量

原子性操作库(atomic)提供了多种类型的原子变量,包括bool 、char、short、int、long、long long等基本数据类型,以及intmax_t、uintmax_t、intptr_t等扩展类型。每个原子变量都有对应的原子类型,比如atomic_bool、atomic_char、atomic_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); // 创建一个原子整型变量并初始化为0

    counter++; // 原子操作:递增counter的值

    int value = counter.load(); // 原子操作:读取counter的值
    std::cout << "Counter value: " << value << std::endl;

    counter.store(10); // 原子操作:将counter的值设置为10

    bool 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++、算法和编程的奥秘。祝您生活愉快,排便顺畅!

2b8dd8add78842b5aadcc661e9255f47.png

目录
相关文章
|
2月前
|
API C++ Windows
Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法
本文介绍Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法,提供官方下载链接与系统修复工具使用指南。
583 2
|
2月前
|
Ubuntu API C++
C++标准库、Windows API及Ubuntu API的综合应用
总之,C++标准库、Windows API和Ubuntu API的综合应用是一项挑战性较大的任务,需要开发者具备跨平台编程的深入知识和丰富经验。通过合理的架构设计和有效的工具选择,可以在不同的操作系统平台上高效地开发和部署应用程序。
144 11
|
2月前
|
缓存 算法 程序员
C++STL底层原理:探秘标准模板库的内部机制
🌟蒋星熠Jaxonic带你深入STL底层:从容器内存管理到红黑树、哈希表,剖析迭代器、算法与分配器核心机制,揭秘C++标准库的高效设计哲学与性能优化实践。
C++STL底层原理:探秘标准模板库的内部机制
|
2月前
|
IDE 编译器 开发工具
msvcp100.dll,msvcp120.dll,msvcp140.dll,Microsoft Visual C++ 2015 Redistributable,Visual C++ 运行库安装
MSVC是Windows下C/C++开发核心工具,集成编译器、链接器与调试器,配合Visual Studio使用。其运行时库(如msvcp140.dll)为程序提供基础函数支持,常因缺失导致软件无法运行。通过安装对应版本的Microsoft Visual C++ Redistributable可解决此类问题,广泛应用于桌面软件、游戏及系统级开发。
335 2
|
3月前
|
并行计算 C++ Windows
|
6月前
|
存储 安全 编译器
c++入门
c++作为面向对象的语言与c的简单区别:c语言作为面向过程的语言还是跟c++有很大的区别的,比如说一个简单的五子棋的实现对于c语言面向过程的设计思路是首先分析解决这个问题的步骤:(1)开始游戏(2)黑子先走(3)绘制画面(4)判断输赢(5)轮到白子(6)绘制画面(7)判断输赢(8)返回步骤(2) (9)输出最后结果。但对于c++就不一样了,在下五子棋的例子中,用面向对象的方法来解决的话,首先将整个五子棋游戏分为三个对象:(1)黑白双方,这两方的行为是一样的。(2)棋盘系统,负责绘制画面。
93 0
|
10月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
6月前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
175 0
|
6月前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。
266 0