新闻中心

c++中std::atomic原子操作入门_c++多线程安全的原子操作详解

2025-11-15
浏览次数:
返回列表
std::atomic用于实现线程安全的原子操作,避免数据竞争。它支持load、store、fetch_add等原子函数,并可通过compare_exchange_weak实现CAS操作,常用于无锁编程;需注意仅适用于平凡可复制类型,默认内存序seq_cst保证最强一致性,但高并发下应权衡性能与正确性。

c++中std::atomic原子操作入门_c++多线程安全的原子操作详解

在C++多线程编程中,std::atomic 是实现线程安全操作的核心工具之一。它用于对共享变量进行原子访问,避免数据竞争(data race),从而保证程序的正确性。本文将从入门角度讲解 std::atomic 的基本用法、常见操作和注意事项,帮助你理解如何在多线程环境中安全地使用原子变量。

什么是原子操作?

原子操作是指一个操作在执行过程中不会被其他线程中断。也就是说,该操作要么完全执行,要么完全不执行,不存在中间状态。在多线程环境下,多个线程同时读写同一个变量时,如果没有同步机制,就可能发生数据竞争。

例如两个线程同时对一个全局 int 变量做自增操作(i++),这个操作实际上包含“读-改-写”三个步骤,不是原子的。如果不加保护,最终结果可能小于预期值。

使用 std::atomic 可以让这些操作变成原子的,确保线程安全。

基本用法与常用类型

std::atomic 是一个模板类,可以包装支持原子操作的类型,如 bool、int、指针等。

常见特化类型包括:

  • std::atomic_int —— 原子整型(推荐使用 std::atomic
  • std::atomic_bool —— 原子布尔值
  • std::atomic —— 原子指针,支持指针算术

示例:使用 atomic 实现线程安全计数器

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

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

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

int main() {
    std::vector<std::thread> threads;
    for (int i = 0; i < 4; ++i) {
        threads.emplace_back(increment);
    }

    for (auto& t : threads) {
        t.join();
    }

    std::cout << "Final counter value: " << counter.load() << '\n';
    return 0;
}

上面代码中,多个线程并发调用 fetch_add 对原子变量进行递增,最终结果一定是 400000,不会出现数据竞争。

常用的原子操作函数

std::atomic 提供了多种成员函数来执行不同的原子操作:

Reachout.ai Reachout.ai

一个AI驱动的视频开发平台,专为忙碌的企业家和销售团队打造

Reachout.ai 142 查看详情 Reachout.ai
  • load():原子地读取当前值
  • store(val):原子地写入新值
  • exchange(val):设置新值,并返回旧值
  • compare_exchange_weak(expected, desired):比较并交换(CAS),如果当前值等于 expected,则设为 desired,否则将当前值写入 expected
  • fetch_add(), fetch_sub():原子加减,返回原值
  • fetch_and(), fetch_or(), fetch_xor():位运算原子操作

CAS 操作是构建无锁数据结构的基础。例如:

std::atomic<int> val(0);
int expected = 0;
bool success = val.compare_exchange_strong(expected, 1);
// 如果 val 当前为 0,则设为 1;否则 expected 被更新为 val 的实际值

内存顺序(Memory Order)简介

每个原子操作都可以指定内存顺序,控制操作周围的内存访问如何排序。常见的选项有:

  • std::memory_order_relaxed:最弱约束,仅保证原子性,不保证顺序
  • std::memory_order_acquire:用于 load,保证之后的读写不会被重排到此操作之前
  • std::memory_order_release:用于 store,保证之前的读写不会被重排到此操作之后
  • std::memory_order_acq_rel:acquire + release,用于 read-modify-write 操作
  • std::memory_order_seq_cst:默认顺序,最强一致性,所有线程看到的操作顺序一致

大多数情况下使用默认的 seq_cst 就足够了。只有在追求极致性能且理解其含义时才建议使用更弱的内存序。

注意事项与限制

并不是所有类型都能用于 std::atomic。必须是平凡可复制(trivially copyable)的类型,且底层支持原子指令。

例如,std::atomic<:string> 是不允许的,因为 string 不是固定大小,也无法原子操作。

对于复杂对象,应使用互斥锁(mutex)或其他同步机制。

另外,虽然原子操作比锁轻量,但频繁的原子操作仍可能影响性能,尤其是在高争用场景下。

基本上就这些。掌握 std::atomic 能让你写出更高效、更安全的多线程代码。关键是理解原子性、CAS 操作和内存顺序的基本概念。在实际项目中,优先考虑使用 atomic 来替代简单的共享变量读写,避免不必要的锁开销。

以上就是c++++中std::atomic原子操作入门_c++多线程安全的原子操作详解的详细内容,更多请关注其它相关文章!


# 到此  # dz网站建设  # 甘肃网站优化推广多少钱  # 沙头网站建设  # 盘锦seo网络推广市场  # 上海网站推广概况怎么写  # 菏泽网站建设作用  # 球鞋模型网站推广案例图  # 宁波网站建设改版  # 留学网站文案推广方案  # seo如何进阶  # 编解码  # 特化  # 是一个  # 有什么区别  # 多线程安全  # 整型  # 设为  # 多个  # 数据结构  # 多线程  # red  # 同步机制  # 无锁  # stream  # ios  # c++  # ai  # 工具  # c++原子操作 


相关栏目: 【 科技资讯46185 】 【 网络学院92790


相关推荐: AO3同人作品网入口 AO3搜索引擎官网永久地址  内存检查:在VS Code中调试C++时的内存视图  J*aScript实现单选按钮与关联输入框的联动禁用教程  天猫双十一预售商品怎么退款_天猫双十一预售退款操作指南  HTML5原生日期选择器与jQuery UI:实现日期选择器的联动与程序化控制  Promise错误处理:在catch后终止链式then执行的策略  Excel中VLOOKUP的第四个参数是干什么用的_Excel VLOOKUP第四参数作用解析  win11如何卸载Windows更新补丁 Win11解决更新导致系统不稳定的问题【修复】  如何修改开机登录密码_Windows账户安全设置超详细教程【必学】  MongoDB聚合管道:正确匹配对象数组中_id的方法  如何在J*a中使用Locale处理多语言环境  提升屏幕阅读器对“m”时间单位的播报准确性:HTML与CSS组合解决方案  内存疯狂猛猛涨价:主板销量直接腰斩!  Win11 BitLocker密码忘了怎么办 Win11找回BitLocker恢复密钥方法【解决】  蛙漫漫画免费阅读入口_蛙漫官方正版无广告纯净版  邮政快递包裹最新位置 邮政快递实时追踪入口  腾讯QQ邮箱登录入口_QQ邮箱官方网站使用地址  使用J*aScript检测输入元素是否包含在特定类中  Safari怎么安装扩展程序 浏览器插件安装与管理方法【详解】  优化大型XML文件解析:基于Python流式处理的内存高效方案  一加 14R 快充无反应_一加 14R 充电优化  Safari浏览器输入栏卡顿如何解决 Safari搜索建议与缓存清理  AO3官网镜像链接 Archive of Our Own同人文在线浏览  Vue.js 图片显示异常排查:理解应用挂载范围与DOM ID唯一性  b站怎么看视频的弹幕数量_b站弹幕数量查看方法  学习通在线学习平台 学习通网页版直接进入课程中心  Linux如何构建多环境配置管理_Linux多环境配置方案  TikTok评论显示延迟如何处理 TikTok评论刷新优化方法  《主播少女的秘密账号迷宫》首支宣传片  Win11怎么查看电脑配置_Win11硬件配置检测工具使用  J*a递归快速排序中静态变量导致数据累积的陷阱与解决方案  cad怎么合并重叠的线段_cad清理重复重叠线条的操作方法  夸克浏览器图书入口 夸克手机浏览器阅读入口  拼多多赚钱渠道_拼多多收益来源  腾讯QQ邮箱官方网站_QQ邮箱网页版在线登录  Composer的 "conflict" 字段有什么用_如何声明不兼容的包以避免依赖冲突  处理Kafka消费者会话超时:深入理解消息处理语义与幂等性  css滚动动画效果怎么实现_使用Animate.css滚动触发动画类  怎么在html里运行vbs脚本_html中运行vbs脚本方法【教程】  Win11怎么合并任务栏图标 Win11开启任务栏合并减少图标占空间【方法】  小米Civi 4录制视频过暗_小米Civi 4亮度优化  没有大陆身份证/银行卡如何实名微信? 亲测有效的几种方法分享  漫蛙漫画登录站点 漫蛙2正版漫画快速访问  VS Code远程开发时如何处理文件权限问题  为什么简单的XML文件也会解析失败? 检查隐藏的非打印字符(如BOM)的方法  树莓派传感器触发:通过Twilio API发送WhatsApp消息教程  在Pyomo中实现基于变量的条件约束:Big-M方法详解  微博网页版直接访问 微博网页版账号管理快速入口  J*a实现学校排课程序_面向对象结构化项目示例  Python自定义类排序:解决lambda键值访问TypeError的实践指南 

搜索