当前位置: 首页 > article >正文

【C++八股】std::atomic —— 原子操作

std::atomic 是 C++11 引入的模板类,主要用于多线程编程中的原子操作,确保在多个线程访问或修改共享变量时不会产生数据竞争。

1. std::atomic 的作用

在多线程环境下,普通变量的操作不是原子的,可能被多个线程同时访问和修改,导致数据竞争

示例(非原子操作可能导致错误):

#include <iostream>
#include <thread>

int counter = 0;  // 非原子变量

void increment() {
    for (int i = 0; i < 100000; ++i) {
        ++counter;  // 可能导致数据竞争
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);
    t1.join();
    t2.join();
    std::cout << "Counter: " << counter << std::endl;  // 可能得到不确定的结果
}

这里 ++counter 不是原子操作,两个线程可能会同时读取 counter,然后都执行 ++,导致最终结果错误。

解决方案:使用 std::atomic

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

std::atomic<int> counter(0);  // 使用 std::atomic

void increment() {
    for (int i = 0; i < 100000; ++i) {
        ++counter;  // 线程安全的操作
    }
}

int main() {
    std::thread t1(increment);
    std::thread t2(increment);
    t1.join();
    t2.join();
    std::cout << "Counter: " << counter << std::endl;  // 结果始终正确
}

std::atomic<int> 确保 counter 的所有操作都是原子的,消除了数据竞争。

2. std::atomic 的核心特点

  1. 保证原子性:所有操作(如 ++--、赋值等)都是不可分割的,不会被其他线程中断。
  2. 无锁实现:通常使用硬件级的原子指令(如 lock cmpxchg),比互斥锁 std::mutex 开销更低。
  3. 支持基本类型:如 intboolfloatpointer 等,也支持自定义类型(但要求是 TriviallyCopyable)。
  4. 支持原子操作
  • fetch_add() / fetch_sub() (类似 ++--
  • compare_exchange_strong() / compare_exchange_weak() (CAS 操作)
  • load() / store() (获取和设置值)

3. std::atomic vs std::mutex

  • std::atomic 适用于简单的数值或指针变量,能够提供高效的原子操作。
  • std::mutex 适用于更复杂的多线程同步需求,比如保护多个变量复杂数据结构

总结

std::atomic 适用于多线程环境,提供无锁原子操作,避免数据竞争
std::mutex 更高效,但只适用于简单变量(int、指针等)
支持 CAS(比较交换)、fetch_add、fetch_sub 等常见原子操作
对于复杂数据结构(如链表、队列),推荐使用 std::mutexstd::shared_mutex

重点

  1. std::atomic 是什么?

    • 是 C++11 引入的无锁原子操作,适用于多线程共享变量。
  2. std::mutex 的区别?

    • std::atomic 无锁,开销低,适用于简单变量。
    • std::mutex 需要锁,开销高,适用于复杂数据结构。
  3. compare_exchange_strong() 的作用?

    • CAS 操作,仅当预期值相等时才更新,适用于无锁数据结构。
  4. 什么时候用 std::atomic_flag

    • 适用于自旋锁,比 std::mutex 更轻量,但可能导致 CPU 忙等。

📢 总结:如果你想提高多线程性能,优先考虑 std::atomic,但如果涉及多个变量或复杂数据结构,还是用 std::mutex 更安全! 🚀


http://www.kler.cn/a/539431.html

相关文章:

  • 机器学习笔记
  • postgresql 游标(cursor)的使用
  • Spring统一修改RequestBody
  • Http 的响应码有哪些? 分别代表的是什么?
  • 多光谱成像技术在华为Mate70系列的应用
  • 大数据项目2a:基于spark的电影推荐和分析系统设计与实现
  • ASP.NET Core 如何使用 C# 向端点发出 POST 请求
  • openAI官方prompt技巧(二)
  • 基于springboot+vue的文物管理系统的设计与实现
  • android手机安装deepseek-r1:1.5b
  • DeepSeek开源多模态大模型Janus-Pro部署
  • 在 Linux 系统下,解压 `.tar.gz`
  • 14vue3实战-----获取用户信息和用户的菜单树信息
  • 解决Redisson在Kubernetes中连接旧Redis主节点的问题
  • Vue3 进阶-自定义事件用法全解析 ✨
  • 大语言模型需要的可观测性数据的关联方式
  • LeetCode热题100-最大子数组和【JavaScript讲解】
  • webpack配置之---output.filename
  • 【DeepSeek】私有化本地部署图文(Win+Mac)
  • Windows编程:在 VS2010 里面,打开一个项目
  • #渗透测试#批量漏洞挖掘#WookTeam searchinfo SQL注入漏洞
  • Vue 3 中的 reactive 和 ref 有什么区别?
  • IDEA关联Tomcat,部署JavaWeb项目
  • kafka服务端之延时操作实现原理
  • NLP论文速读(ICLR 2025)|在实时机器翻译中对齐人类偏好
  • 基于spring boot的餐厅点餐管理系统设计与实现(LW+源码+讲解)