新闻中心

c++怎么使用原子操作std::atomic_c++无锁并发与原子变量用法

2025-11-12
浏览次数:
返回列表
原子操作是不可中断的操作,std::atomic 提供对共享变量的原子访问,支持 load、store、fetch_add 等操作,默认使用 seq_cst 内存序,可用于实现无锁计数器或自旋锁,提升多线程程序性能与安全性。

c++怎么使用原子操作std::atomic_c++无锁并发与原子变量用法

在C++中,std::atomic 是实现无锁并发编程的核心工具之一。它保证对共享变量的读写操作是原子的,避免多个线程同时访问时产生数据竞争,从而提高程序性能和线程安全性。

什么是原子操作?

原子操作是指一个操作在执行过程中不会被其他线程中断,要么完全执行,要么不执行。在多线程环境中,对共享变量的普通读写可能引发竞态条件(race condition),而使用 std::atomic 可以确保操作的原子性,无需加锁也能安全访问。

基本用法:定义和初始化原子变量

std::atomic 可用于整型、指针等类型。常用的基本形式如下:

  • std::atomic counter{0}; —— 原子整数,初始值为0
  • std::atomic ready{false}; —— 原子布尔值
  • std::atomic ptr{nullptr}; —— 原子指针

支持的操作包括 load(读)、store(写)、fetch_add、fetch_sub、exchange、compare_exchange_weak/strong 等。

常见原子操作函数说明

以下是常用的成员函数及其用途:

  • load():原子地读取当前值
  • store(val):原子地写入新值
  • fetch_add(n):原子增加n,返回旧值
  • fetch_sub(n):原子减少n,返回旧值
  • exchange(val):设置新值,并返回旧值
  • compare_exchange_weak(expected, desired):如果当前值等于 expected,则设为 desired,否则更新 expected
  • compare_exchange_strong(...):与 weak 类似,但不会因虚假失败而返回 false

这些操作默认使用最强内存序 std::memory_order_seq_cst,确保顺序一致性。

实际示例:线程安全计数器

下面是一个使用 std::atomic 实现无锁计数器的例子:

千鹿Pr助手 千鹿Pr助手

智能Pr插件,融入众多AI功能和海量素材

千鹿Pr助手 128 查看详情 千鹿Pr助手
#include <iostream>
#include <thread>
#include <vector>
#include <atomic>

std::atomic<int> count{0};

void increment() {
    for (int i = 0; i < 1000; ++i) {
        count.fetch_add(1);
    }
}

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

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

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

这个例子中,多个线程并发调用 fetch_add,由于原子性保障,最终结果一定是10000,不会出现数据竞争。

compare-and-swap 实现无锁逻辑

利用 compare_exchange_weak 可以实现更复杂的无锁结构,比如无锁栈或标志位控制:

std::atomic<bool> lock_flag{false};

bool try_lock() {
    bool expected = false;
    return lock_flag.compare_exchange_strong(expected, true);
}

void unlock() {
    lock_flag.store(false);
}

这段代码模拟了一个简单的无锁自旋锁。只有当 lock_flag 为 false 时,才能将其设为 true 并获得“锁”。

内存序(Memory Order)的选择

std::atomic 的操作可以指定内存序来优化性能。常见的选项有:

  • std::memory_order_relaxed:只保证原子性,不提供同步或顺序约束
  • std::memory_order_acquire:用于 load,保证之后的读写不会被重排到该操作之前
  • std::memory_order_release:用于 store,保证之前的读写不会被重排到该操作之后
  • std::memory_order_acq_rel:同时具有 acquire 和 release 语义
  • std::memory_order_seq_cst:默认,最严格的顺序一致性

例如,计数器场景可使用 relaxed 模式提升性能:

count.fetch_add(1, std::memory_order_relaxed);

基本上就这些。合理使用 std::atomic 能写出高效、安全的无锁代码,但要注意不是所有类型都支持原子操作(如不能直接对自定义结构体使用 std::atomic,除非特化或使用 atomic_ref 等)。掌握原子变量和内存模型是深入并发编程的关键一步。

以上就是c++++怎么使用原子操作std::atomic_c++无锁并发与原子变量用法的详细内容,更多请关注其它相关文章!


# 如何使用  # 罗湖区网站推广收费情况  # 优化网站培训内容运营  # 普洱php网站建设  # 东营广饶商务网站建设  # 达州短视频营销推广招聘  # 北面的营销和推广  # 免费的推广网站推荐软件  # 孝义本地网站推广指导  # 柳州湖南网站优化推广  # seo标点符号空格  # 内存管理  # 特化  # 是一个  # 到该  # 工具  # 更快  # 整型  # 设为  # 多个  # 多线程  # red  # 无锁  # 并发编程  # stream  # ios  # c++  # ai  #  


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


相关推荐: HuggingFaceEmbeddings中向量嵌入维度调整的限制与理解  高德地图公交到站提醒失败如何解决 高德提醒权限设置  在Go Martini框架中高效服务动态生成图像的实践指南  谷歌浏览器如何快速清除某个网站的数据_Chrome网站缓存清理方法  Win11怎么用U盘重装系统 Win11制作启动盘并重装系统完整教程【详解】  LINUX怎么设置定时任务_LINUX crontab配置教程  微信网页版官方入口直达 微信网页版网页版登录使用方法  如何使用 Excel 发布器与 Power BI 分享 Excel 洞察  J*a里如何实现订单支付与库存同步功能_支付库存同步项目开发方法说明  Go Martini框架:动态服务解码后的图片内容  J*a应用程序首次运行自动创建文件与目录的最佳实践  新手怎么开始学化妆 零基础化妆入门教程  汽水音乐车机版8.9下载 汽水音乐车机版8.9版本安装入口  夸克浏览器图书入口 夸克手机浏览器阅读入口  使用 Pandas 高效处理 .dat 文件:数据清洗与数值计算实战  支付宝碰一碰设备是REDMI手机吗 博主拆机辟谣:处理器、内存都不一样  Flexbox布局实践:实现粘性导航栏与底部固定页脚  AO3官方镜像站点汇总 AO3同人作品网页版直达链接  C++编译期如何执行复杂计算_C++模板元编程(TMP)技巧与应用  Mac怎么使用表情符号_Mac Emoji快捷键面板  AO3最新镜像入口 Archive of Our Own官方平台访问  J*aScript类型检查_j*ascript代码规范  品牌机怎么重装系统 联想/戴尔/惠普笔记本恢复出厂系统教程  Spyder启动失败:字体文件权限拒绝错误解决方案  J*aScript中向JSON对象添加新属性的正确姿势  印象笔记怎样用批量导出备知识库_印象笔记用批量导出备知识库【备份方法】  夸克AO3官网入口_AO3镜像网站2025推荐  魅族20怎样在浏览器开无图省流_iPhone魅族20浏览器开无图省流【流量节省】  excel如何生成目录 excel一键生成工作表目录超链接  2025AO3夸克浏览器通道_AO3手机HTTPS安全入口分享  一加Ace 6T实拍样张首次公布!李杰:主摄实力完全看齐4K档性能旗舰  谷歌浏览器浏览体验优化_谷歌浏览器新版直连永久可用提示  Go语言中的*string:深入理解字符串指针  Safari自带网页翻译功能怎么用 无需插件轻松看懂外文网站【方法】  win11专注助手在哪 Win11免打扰模式设置与自动化规则【指南】  PDO预处理语句中冒号的正确处理:区分SQL函数格式与命名占位符  Win11怎么合并任务栏图标 Win11开启任务栏合并减少图标占空间【方法】  解决Rails应用中内容错位与Turbo警告:meta标签误用导致富文本渲染异常  深入理解Google Cloud Datastore查询:祖先路径与数据一致性  如何使用J*aScript精确选择并批量修改特定父元素下子链接的样式  邮政编码查询不到怎么办_邮政编码查询不到的常见原因与对策  React Router 嵌套组件中 URL 重定向问题的解决方案  Archive of Our Own官网直达 AO3最新可用地址一览  Golang如何测试channel通信行为_Golang channel通信测试与分析方法  在FastAPI中利用lifespan与依赖注入高效管理Redis连接池  Yandex免登录官网入口_俄罗斯Yandex搜索引擎直达链接  曝R星经典之作开发图 设计简陋但信息密集!  微信网页版扫码登录入口 微信网页版二维码登录入口  uc浏览器网页版入口 uc浏览器网页版最新网址  mysql密码锁定怎么解锁_mysql密码锁定解锁后修改密码步骤 

搜索