C++ 原子变量atomic variable

news/2024/9/14 2:15:06 标签: c++, 开发语言

原子变量

原子变量(atomic variable)是 C++11 引入的一种同步机制,用于在多线程环境中进行无锁的、线程安全的操作。原子变量的操作是不可分割的,即在执行过程中不会被其他线程中断,从而避免了数据竞争和不一致的问题。原子变量位于 头文件中。

基本概念

原子性

原子性:一个操作是原子的,意味着它在执行过程中不会被其他线程中断。原子操作要么完全执行,要么完全不执行,不存在部分执行的状态。

数据竞争

数据竞争:当多个线程同时访问同一个内存位置,并且至少有一个线程在写入数据时,就会发生数据竞争。数据竞争可能导致未定义行为和数据不一致。

原子变量的类型

C++ 标准库提供了多种原子类型,包括:

std::atomic:模板类,可以用于任何可复制的类型 T。

特化类型:如 std::atomic_bool、std::atomic_int、std::atomic_uint 等。

基本用法

定义原子变量:

#include <atomic>

std::atomic<int> atomic_int;
std::atomic_bool atomic_bool;

原子操作

原子变量支持多种原子操作,包括:

加载(load):读取原子变量的值。

存储(store):写入原子变量的值。

交换(exchange):将原子变量的值替换为新值,并返回旧值。

比较交换(compare-exchange):如果原子变量的值等于预期值,则将其替换为新值,并返回操作是否成功。

#include <atomic>
#include <iostream>

int main() {
    std::atomic<int> atomic_int(0);

    // 加载操作
    int value = atomic_int.load();
    std::cout << "Loaded value: " << value << std::endl;

    // 存储操作
    atomic_int.store(42);
    std::cout << "Stored value: " << atomic_int.load() << std::endl;

    // 交换操作
    int old_value = atomic_int.exchange(99);
    std::cout << "Exchanged value: " << old_value << ", new value: " << atomic_int.load() << std::endl;

    // 比较交换操作
    int expected = 99;
    bool success = atomic_int.compare_exchange_strong(expected, 100);
    std::cout << "Compare-exchange result: " << success << ", expected: " << expected << ", new value: " << atomic_int.load() << std::endl;

    return 0;
}

内存顺序

原子操作可以指定内存顺序(memory order),用于控制内存访问的顺序和可见性。C++ 提供了多种内存顺序选项,包括:

  1. std::memory_order_relaxed
    特点:最宽松的内存顺序,不保证顺序和可见性。
    用途:适用于不需要顺序保证的场景,如简单的计数器。
  2. std::memory_order_consume
    特点:保证依赖关系的顺序。
    用途:适用于依赖关系的数据依赖场景。
  3. std::memory_order_acquire
    特点:保证读取操作的顺序。
    用途:适用于读取操作需要顺序保证的场景。
  4. std::memory_order_release
    特点:保证写入操作的顺序。
    用途:适用于写入操作需要顺序保证的场景。
  5. std::memory_order_acq_rel
    特点:同时保证读取和写入操作的顺序。
    用途:适用于读取和写入操作都需要顺序保证的场景。
  6. std::memory_order_seq_cst
    特点:最严格的内存顺序,保证所有线程看到的操作顺序一致。
    用途:适用于需要最强顺序保证的场景。
#include <atomic>
#include <iostream>

int main() {
    std::atomic<int> atomic_int(0);

    // 使用 memory_order_seq_cst 进行存储操作
    atomic_int.store(42, std::memory_order_seq_cst);

    // 使用 memory_order_seq_cst 进行加载操作
    int value = atomic_int.load(std::memory_order_seq_cst);
    std::cout << "Loaded value: " << value << std::endl;

    return 0;
}

示例代码

以下是一个完整的示例,展示了如何在多线程环境中使用原子变量进行线程安全的计数:

#include <atomic>
#include <iostream>
#include <thread>
#include <vector>

std::atomic<int> counter(0);

void increment_counter() {
    for (int i = 0; i < 1000; ++i) {
        counter.fetch_add(1, std::memory_order_relaxed);
    }
}

int main() {
    std::vector<std::thread> threads;

    // 创建多个线程进行计数
    for (int i = 0; i < 10; ++i) {
        threads.emplace_back(increment_counter);
    }

    // 等待所有线程完成
    for (auto& t : threads) {
        t.join();
    }

    // 输出最终计数结果
    std::cout << "Final counter value: " << counter.load() << std::endl;

    return 0;
}

Final counter value: 10000

总结

原子变量:用于在多线程环境中进行无锁的、线程安全的操作。

原子性:确保操作是不可分割的,避免数据竞争和不一致。

内存顺序:控制内存访问的顺序和可见性,提供多种选项以满足不同需求。

应用场景:适用于需要线程安全的计数器、标志位等场景。


http://www.niftyadmin.cn/n/5641141.html

相关文章

【工具与中间件】百度翻译API实战

文章目录 前言1. 注册与代码Demo1.1 注册1.2 代码Demo 2. 实战2.1 运行Demo2.2 配置环境变量2.3 编写实际代码并操作2.3.1 准备基础代码2.3.2 准备FastJson2.3.3 单体条数据翻译测试2.3.4 执行翻译 3. 总结参考资料 百度翻译API实战 记一次使用百度翻译API翻译表数据 前言 …

提前购|基于SSM+vue的创新型产品提前购平台(源码+数据库+文档)

创新型产品提前购平台 基于SSMvue的创新型产品提前购平台 一、前言 二、系统设计 三、系统功能设计 系统功能实现 后台模块实现 管理员模块实现 发布企业管理实现 个体管理实现 投资企业管理实现 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选…

MySQL数据类型-介绍

MySQL 支持多种数据类型&#xff0c;这些数据类型可以根据它们所存储的数据类型大致分为几类&#xff1a;数值类型、日期和时间类型、字符串&#xff08;字符&#xff09;类型、空间数据类型以及JSON数据类型。 一、数据类型 1.整数类型 TINYINT&#xff1a;非常小的整数。例…

9 自研rgbd相机基于rk3566之qt框架开发主线程与opengl_widget点云显示

qt框架开发opengl_widget点云显示 mainwindow主线程代码详解1 主线程功能:2 主线程代码示例:Qopenglwidget点云显示类代码详解1 qtopenglwidget框架介绍:2 qtopenglwidget渲染流程:3 qtopenglwidget顶点与片段着色器配置示例:4 qtopenglwidget主线程更新点云函数:5 qtope…

python常用库学习-Matplotlib使用

文章目录 安装 Matplotlib导入库基本示例1. 绘制简单的线图2. 散点图3. 柱状图4. 直方图5. 子图 更多高级功能1. 自定义样式2. 文本和注释3. 保存图形 示例&#xff1a;使用 Matplotlib 绘制多个图表示例 1: 绘制多个线图示例 2: 绘制散点图和直方图 参考文献 Matplotlib 是 Py…

探索NVIDIA RTX 4060 8G与RTX 3060 12G:性能与适用场景的深度解析

在考虑NVIDIA RTX 4060 8G和RTX 3060 12G两种配置时&#xff0c;我们需要根据具体的应用场景来做出选择。RTX 4060 8G显卡以其较快的处理速度而著称&#xff0c;适合需要快速响应的任务&#xff0c;如实时渲染、视频编辑和部分机器学习任务。而RTX 3060 12G显卡则因其较大的显存…

RPC框架需要解决的问题

RPC&#xff08;Remote Procedure Call&#xff09;框架是分布式系统中的关键组件&#xff0c;用于在不同的网络节点之间进行远程服务调用。一个成熟的 RPC 框架需要解决一系列技术问题&#xff0c;以确保系统的高效性、可靠性和可扩展性。本文将详细探讨 RPC 框架需要解决的核…

【JAVA】第三天

【JAVA】第三天 一、面向对象1.static2.代码块 二、继承三、权限修饰符四、方法重写五、多态1.自动类型转换2.强制类型转换 六、final七、抽象类八、接口九、内部类十、枚举十一、泛类1.泛型类2.泛型接口3.泛型方法 一、面向对象 1.static 类变量&#xff1a;属于类&#xff…