当前位置: 首页> 文旅> 美景 > 庆阳网站优化公司_怎么自己开一个平台_软文什么意思_苏州seo排名优化课程

庆阳网站优化公司_怎么自己开一个平台_软文什么意思_苏州seo排名优化课程

时间:2025/8/23 16:17:38来源:https://blog.csdn.net/hujiahangdewa/article/details/145598553 浏览次数:0次
庆阳网站优化公司_怎么自己开一个平台_软文什么意思_苏州seo排名优化课程

祝大家元宵节快乐!!!
天天开心

文章目录

  • 一、原子变量
  • 二、原子操作
  • 三、原子操作的内存序问题
  • 四、atomic的成员函数
  • 总结


一、原子变量

原子变量是指使用std::atomic模板类定义的变量,这些变量提供了对其所表示的值进行原子操作的能力。原子变量确保在多线程环境中,对变量的读写操作是线程安全的,即操作不会被其他线程中断或干扰。
在这里插入图片描述
原子变量的定义

#include <atomic>std::atomic<int> atomicInt(0);//定义一个int型的原子变量,名称为atomicInt,初始值为0

二、原子操作

原子操作是指对原子变量进行的不可分割的操作。不可分割的意思是这些操作要么完全执行,要么完全不执行,不会在执行过程中被其他线程打断。这些操作包括基本的读取、写入、交换、比较并交换(CAS)以及一些算术和按位操作。
在这里插入图片描述
接下来我们来看一个例子:

#include <iostream>
#include <thread>
#include <atomic>
using namespace std;int num = 0;void addNum()
{for (int i = 0; i < 1000000; i++){num++;}
}int main()
{thread t1(addNum);thread t2(addNum);t1.join();t2.join();cout<<num<<endl;return 0;
}

以上这个例子中我们输出num的值,可能不是1000000,因为两个线程共用一个变量,我们必须加上锁或者将num变成原子变量才可以解决这个问题。

#include <iostream>
#include <thread>
#include <atomic>
using namespace std;atomic<int> num(0);void addNum()
{for (int i = 0; i < 1000000; i++){num++;}
}int main()
{thread t1(addNum);thread t2(addNum);t1.join();t2.join();cout<<num<<endl;return 0;
}

注意,如果我们将num++换成num=num+1,这个输出的结果也还是错的,因为num=num+1这个式子不是原子操作
常见的原子操作有如下几种:

  • 加载和存储操作
int value=atomicInt.load();//原子加载
atomicInt.store(10);//原子存储
  • 读写操作(等价于load和store)
int value=atomicInt;//原子读取
atomicInt=10;//原子写入
  • 自增和自减操作
atomicInt++;//原子自增
atomicInt--;//原子自减
++atomicInt;//前置自增
---atomicInt;//前置自减
  • 其他修改操作
atomicInt+=5;//原子加
atomicInt-=3;//原子减
  • 高级操作----compare_exchange:比较并交换操作,用于实现无锁数据结构等复杂同步机制。
int expected=0;
int desired=1;
if(atomicInt.compare_exchange(expected,desired)){//如果atomicInt的当前值等于expected,则将其设置为desired//并返回true,否则将expected更新为atomicInt的当前值。返回false
}

三、原子操作的内存序问题

在多线程编程中,内存顺序问题是由编译器和处理器的优化行为引起的。为了提高性能,编译器和处理器可能会对内存操作(如读取和写入)进行重排。这种重排行为在单线程程序中通常不会引起问题,但在多线程程序中,重排可能会导致线程间的数据竞争和不可预测的行为。
在这里插入图片描述
内存顺序定义了多线程环境中操作的可见性和顺序规则,确保线程间的同步
原子操作可以指定不同的内存顺序,以控制操作的可见性和排序
在这里插入图片描述
内存序不会影响原子操作的原子性。即使在最弱的std::memory_order_relaxed内存序下,操作仍然是原子的,不可中断。然而,内存序会影响操作的可见性和顺序。

四、atomic的成员函数

在C++中,std::atomic类模板提供了一些操作符和成员函数,用于执行原子操作。这些操作符和成员函数保证在多线程环境下对原子变量的操作是线程安全的。以下是std::atomic支持的一些主要原子操作和成员函数:

原子操作符

操作符作用
=用于赋值
+原子变量之间相加
+=原子变量自增
-原子变量之间相减
-=原子变量自减
  1. is_lock_free()
    ·检查该原子操作是否是无锁的
    ·返回值:bool

  2. load(memory_order order=memory_order_seq_cst) const:
    ·原子读取并返回当前值
    ·参数:内存顺序(可选)
    ·返回值:当前值

  3. store(T desired,memory_order order=memory_order_seq_cst)
    ·原子地将值desired存储到对象中。
    ·参数:存储值和内存顺序(可选)

  4. exchange(T desired,memory_order order=memory_order_seq_cst)
    ·原子地将值desired存储到对象中,并返回之前的值。
    ·参数:存储的值和内存顺序(可选)

  5. compare_exchange_weak(T &expected,T desired,memory_order success,memory_order failure)
    ·如果当前值等于expected,则将其替换为desired,并返回true,否则返回false并将expected更新为当前值
    ·参数:期望值引用,新的值,成功和失败的内存顺序
    ·返回值:bool

  6. compare_exchange_strong(T &expected,T desired,memory_order success,memory_order failure)
    ·类似于compare_exchange_weak,但具有更强的保证,即它不会由于伪失败而返回false。
    ·参数和返回值同compare_exchange_weak

  7. fetch_add(T arg,memory_order order=memory_order_seq_cst)
    ·原子地将当前值增加arg,并返回之前的值
    ·参数:增加的值和内存顺序(可选)
    ·返回值:之前的值

  8. fetch_sub(T arg,memory_order order=memory_order_seq_cst)
    ·原子地将当前值减少arg,并返回原来的值
    ·参数:减少的值和内存顺序(可选)
    ·返回值:之前的值

  9. fetch_and(T arg,memory_order order=memory_order_seq_cst)
    ·原子地将当前值与arg进行按位与运算,并返回之前的值
    ·参数:按位与的值和内存顺序(可选)
    ·返回值:之前的值

  10. fetch_or(T arg,memory_order order=memory_order_seq_cst)
    ·原子地将当前值与arg进行按位或运算,并返回之前的值
    ·参数:按位或的值和内存顺序(可选)
    ·返回值:之前的值

  11. fetch_xor(T arg,memory_order order=memory_order_seq_cst)
    ·原子地将当前值与arg进行按位异或运算,并返回之前的值
    ·参数:按位异或的值和内存顺序(可选)
    ·返回值:之前的值

总结

这篇技术文章聚焦 C++ 中的原子变量,开篇点明原子变量是用std::atomic模板类定义,能在多线程下确保操作线程安全,避免读写受干扰。接着阐述原子操作不可分割,介绍其基本类型,如读写、交换、CAS 等,并通过代码示例对比非原子与原子变量在多线程下的表现。随后深入探讨原子操作的内存序问题,强调多线程下内存操作重排可能引发的风险,以及内存顺序对操作可见性和排序的控制作用,且不影响原子性。最后,以表格列举结合文字说明的方式,详细介绍了std::atomic的成员函数,包括操作符及 11 个主要成员函数的功能、参数与返回值,为读者全面理解和运用 C++ 原子变量提供了清晰的知识框架。

关键字:庆阳网站优化公司_怎么自己开一个平台_软文什么意思_苏州seo排名优化课程

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: