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

C++20中的std::atomic_ref

一、std::atomic_ref

我们在学习C++11后的原子操作时,都需要提前定义好std::atomic变量,然后才可以在后续的应用程序中进行使用。原子操作的优势在很多场合下优势非常明显,所以这也使得很多开发者越来习惯使用原子变量。
但是,在实际的开发场景中,有一些情况变量已经被定义或者说被封装,再想更改使用相关的变量非常麻烦或者说不可能,有没有一些方法可以将其转成原子操作呢?这就是在C++20中提供的std::atomic_ref。它可以把变量转成原子引用(即对其引用的对象进行原子操作,笔者自己为记忆方便定义为原子引用)。先看其定义:

template< class T >
struct atomic_ref;

其内部支持wait、notify_one和notify_all等线程间的同步机制。那么在多线程中应用更灵活方便。

二、应用和限制

std::atomic_ref特别适合那些与其它模块甚至第三方已定义完成的对象定义进行原子操作控制。这样,在简单的应用场景下就可以不用再考虑多线程的并发问题,减轻了开发者的负担,增加了数据的安全性,提高了性能。其应用简单方便,不必引入过重的锁的控制,既实现了多线程数据间的安全操作又减少了锁的应用造成的较大的开销。
不过,有优势的地方就必然也有受限制的地方:
1、要防止多个地方操作被引用的数据(混合使用),比如直接使用数据和使用std::atomic_ref使用数据,可能会导致数据的混乱,这点可参看普通指针和智能指针混合使用。
2、如果使用const,需要注意:const对std::atomic_ref是浅层的,即可以通过其它地方对引用的数据进行修改,切记
3、使用std::atomic_ref时引用对象要求必须是平凡可复制的且不能是:“is_always_lock_free is false and std::is_volatile_v is true”。
4、和所有的引用一样,std::atomic_ref引用的对象生命周期要长于std::atomic_ref引用本身
5、被原子引用所引用的对象所需的对齐要求,至少为 alignof(T)
6、要选用合理的memory_order,不过在PC机上编程一般std::memory_order_relaxed几乎都可以满足
7、一定要清楚,std::atomic_ref并不是为了替代锁而产生的,所以在实际编程中要综合考虑如何应用同步机制
8、在高并发(并行)操作时,还是需要注意性能瓶颈的产生
应用简单,就更需要注意限制的场景,否则随意使用,极有可能反而达不到实际想要的结果。

三、例程

先看一个基础的例程:

#include <atomic>
#include <iostream>
#include <thread>struct Data {int value;
};
int main() {Data data={0};static int d = 9;std::atomic_ref<int> atomicValue = std::atomic_ref(data.value);std::atomic_ref<int> addValue = std::atomic_ref(d);auto addThread1 = [&atomicValue]() {for (int i = 0; i < 1000; ++i) {atomicValue.fetch_add(1, std::memory_order_relaxed);}};auto addThread2 = [&addValue]() {for (int i = 0; i < 1000; ++i) {addValue.fetch_add(1, std::memory_order_release);}};std::thread t1(addThread1);std::thread t2(addThread1);std::thread t3(addThread2);std::thread t4(addThread2);t1.join();t2.join();t3.join();t4.join();std::cout << "Final value: " << data.value << std::endl; //  2000std::cout << "Final value: " << d << std::endl;//2009addValue.store(20,std::memory_order_relaxed);std::cout<<"read d:"<<addValue.load(std::memory_order_relaxed)<<std::endl;return 0;
}

多线程中的同步,和普通的锁同步一样,这里就不举例子了。可参看一下相关的wait等方法即可。

四、总结

看到std::atomic_ref,其实就想到了智能指针,二者应用的方式何其相似。从目的上来讲就是为了让开发变得简单,特别是在多线程状态下的开发,能简单一些是一些。另外就是为了兼容更多的原有的应用让其都能使用std::atomic的功能。
或者从另外一个角度看,std::atomic_ref只是一个过渡的功能,以后会出现一个更强大的类或接口,让原子操作更简单。让我们拭目以待!

相关文章:

C++20中的std::atomic_ref

一、std::atomic_ref 我们在学习C11后的原子操作时&#xff0c;都需要提前定义好std::atomic变量&#xff0c;然后才可以在后续的应用程序中进行使用。原子操作的优势在很多场合下优势非常明显&#xff0c;所以这也使得很多开发者越来习惯使用原子变量。 但是&#xff0c;在实…...

CSS 相关知识

1、高度已知&#xff0c;三栏布局&#xff0c;左右宽度 200&#xff0c;中间自适应&#xff0c;如何实现&#xff1f; <body><div class"box"><div class"box1">高度已知</div><div class"box2">左右宽度 200&…...

RocketMQ、RabbitMQ、Kafka 的底层实现、功能异同、应用场景及技术选型分析

1️⃣ 引言 在现代分布式系统架构中&#xff0c;&#x1f4e9;消息队列&#xff08;MQ&#xff09;是不可或缺的组件。它在系统&#x1f517;解耦、&#x1f4c9;流量削峰、⏳异步处理等方面发挥着重要作用。目前&#xff0c;主流的消息队列系统包括 &#x1f680;RocketMQ、&…...

IDEA升级出现问题Failed to prepare an update Temp directory inside installation

IDEA升级出现问题"Failed to prepare an update Temp directory inside installation…" 问题来源&#xff1a; 之前修改了IDEA的默认配置文件路径&#xff0c;然后升级新版本时就无法升级&#xff0c;提示"Failed to prepare an update Temp directory insid…...

DeepSeek提示词手册

一、核心原则&#xff1a;基于DeepSeek的推理特性 自然语言优先undefinedDeepSeek擅长理解自然表达&#xff0c;无需复杂模板。例如&#xff1a; ❌旧模板&#xff1a;"你是专业分析师&#xff0c;需分三步回答&#xff0c;第一步…" ✅高效提问&#xff1a;"…...

基于UVM搭验证环境

基于UVM搭验证环境基本思路&#xff1a; 首先&#xff0c;我们搭建环境时一般都有一个目标的DUT。此时&#xff0c;我们可以结合所要验证的的模块、是否需要VIP、验证侧重点等在典型的UVM验证环境的基础上做适当调整后形成一个大体的环境架构。比如&#xff0c;需要一个ahb_vip…...

C++性能优化—人工底稿版

C以高性能著称&#xff0c;性能优化是C程序员绕不过去的一个话题&#xff0c;性能优化是一个复杂、全局而又细节的问题&#xff0c;本文总结C性能分析中常用的知识。 性能优化的时机 大部分关于性能优化的文章都强调&#xff1a;不要过早的进行性能优化。 C编码层面 数据结…...

Java 使用腾讯翻译 API 实现含 HTML 标签文本精准翻译工具

一、翻译标签文本工具 package org.springblade.common.utils;import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern;public class TencentTranslationForHTML {public static void main(String[] args) {Stri…...

十款开源的论坛建站工具

以下是十款开源的论坛建站工具&#xff0c;它们各具特色&#xff0c;能够满足不同用户的需求&#xff1a; Discuz!&#xff08;Crossday Discuz! Board&#xff09; 特点&#xff1a;基础架构采用web编程组合PHPMySQL&#xff0c;用户可以在不需要任何编程的基础上&#xff0c;…...

vue学习6

1. 智慧商城 1. 路由设计配置 单个页面&#xff0c;独立展示的&#xff0c;是一级路由 2.二级路由配置 规则&组件配置导航链接配置路由出口 <template><div id"app"><!--二级路由出口--><router-view></router-view><van-…...

线程池以及日志、线程总结

一、线程池以及日志 1、基础线程池写法 主线程在main函数中构建一个线程池&#xff0c;初始化(Init)后开始工作(Start) 此时线程池中每个线程都已经工作起来了&#xff0c;只是任务队列中任务为空&#xff0c;所有线程处于休眠状态(通过线程同步中的条件变量实现&#xff0c…...

Vue 响应式渲染 - 过滤应用

Vue 渐进式JavaScript 框架 基于Vue2的学习笔记 - Vue响应式渲染综合 - 过滤应用 目录 过滤应用 引入vue Vue设置 设置页面元素 模糊查询过滤实现 函数表达式实现 总结 过滤应用 综合响应式渲染做一个输入框&#xff0c;用来实现&#xff1b;搜索输入框关键词符合列表。…...

【ThreeJS Basics 1-3】Hello ThreeJS,实现第一个场景

文章目录 环境创建一个项目安装依赖基础 Web 页面概念解释编写代码运行项目 环境 我的环境是 node version 22 创建一个项目 首先&#xff0c;新建一个空的文件夹&#xff0c;然后 npm init -y , 此时会快速生成好默认的 package.json 安装依赖 在新建的项目下用 npm 安装依…...

银行国际结算

银行国结项目&#xff0c;即国际结算项目&#xff0c;是银行业务中的重要组成部分&#xff0c;它涉及跨国界的货币收付和资金转移。 一、银行国结项目的定义 银行国结项目是指银行为国际贸易、投资等活动提供的国际结算服务&#xff0c;包括各种国际支付和资金清算业务。这些…...

Go语言构建微服务:从入门到实战

引言 在云原生时代&#xff0c;微服务架构已成为构建复杂分布式系统的首选方案。Go语言凭借其卓越的并发支持、简洁的语法和高效的运行时&#xff0c;成为微服务开发的利器。本文将深入探讨如何用Go构建健壮的微服务系统&#xff0c;并通过完整案例演示关键实现细节。 一、微…...

深入理解动态代理

为什么需要动态代理 对于代码的增强逻辑我们是清楚具体实现的,一种方式是增强逻辑作为委托类,被其他业务类调用, 这样会有很多重复代码,而且,当需要根据动态参数来决定增强逻辑时,重复代码会更多,逻辑会更不清晰 二,也是动态代理产生的原始需求,解决类爆照问题, 所以…...

私有属性和方法(python)

一、私有属性&#xff08;属性名前面加两个短下划线&#xff09; &#xff08;一&#xff09;私有属性与公有属性区别 公有属性&#xff1a;在类里面和外面均可以访问和修改 私有属性&#xff1a;需要用set方法才能修改&#xff0c;get方法才能访问 &#xff08;二&#xf…...

Cherry Studio之DeepSeek联网/本地,建属于自己的AI助理!

上一篇文章&#xff0c;讲了DeepSeek-R1部署到本地的方法。这一篇文章&#xff0c;我们让DeepSeek再一次升级&#xff0c;通过图形化界面来交互&#xff0c;从而变成我们的AI助理&#xff0c;让DeepSeek R1发挥最大实力&#xff01; 首选需要借助硅基流动的API接口&#xff0c…...

TcpClientTest

ClientTest&#xff1a; using System; using System.Net.Sockets; using System.Text;class TcpClientTest {static void Main(string[] args){try{// 创建一个TcpClient实例并连接到服务器 TcpClient client new TcpClient("1vg5062570.51mypc.cn", 43319);//1v…...

IGBT的两级关断

IGBT&#xff08;绝缘栅双极型晶体管&#xff09;的两级关断&#xff08;Two-stage turn-off&#xff09;是一种优化关断过程的方法&#xff0c;主要用于减少关断时的电压过冲和dv/dt&#xff08;电压变化率&#xff09;过高的问题&#xff0c;特别是在大功率应用中&#xff08…...

【STM32】ADC

本次实现的是ADC实现数字信号与模拟信号的转化&#xff0c;数字信号时不连续的&#xff0c;模拟信号是连续的。 1.ADC转化的原理 模拟-数字转换技术使用的是逐次逼近法&#xff0c;使用二分比较的方法来确定电压值 当单片机对应的参考电压为3.3v时&#xff0c;0~ 3.3v(模拟信号…...

从MyBatis-Plus看Spring Boot自动配置原理

一、问题引入&#xff1a;神秘的配置生效之谜 当我们使用MyBatis-Plus时&#xff0c;只需在pom.xml中添加依赖&#xff1a; <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3…...

0基础租个硬件玩deepseek,蓝耘元生代智算云|本地部署DeepSeek R1模型

前言&#xff1a;哈喽&#xff0c;大家好&#xff0c;今天给大家分享一篇文章&#xff01;并提供具体代码帮助大家深入理解&#xff0c;彻底掌握&#xff01;创作不易&#xff0c;如果能帮助到大家或者给大家一些灵感和启发&#xff0c;欢迎收藏关注哦 &#x1f495; 目录 0基础…...

雪花算法应用

什么是雪花算法&#xff1f; 雪花算法是由 Twitter 开源的分布式 ID 生成算法&#xff0c;用于生成 64 位的长整型唯一 ID。其结构如下&#xff1a; - 1 位符号位&#xff1a;始终为 0 - 41 位时间戳&#xff1a;精确到毫秒 - 10 位工作机器 ID&#xff1a;包含 5 位数据中心 …...

Chapter3:结构化程序设计

参考书籍&#xff1a;《C#边做边学》&#xff1b; 3.结构化程序设计 3.1 结构化程序设计的3种基本结构 顺序结构&#xff1a;先执行 A {\rm A} A语句&#xff0c;再执行 B {\rm B} B语句&#xff0c;两者是顺序执行的关系&#xff1b; 选择结构&#xff1a;根据所定选择条件为…...

白话文实战Nacos(保姆级教程)

前言 上一篇博客 我们创建好了微服务项目,本篇博客来体验一下Nacos作为注册中心和配置中心的功能。 注册中心 如果我们启动了一个Nacos注册中心,那么微服务比如订单服务,启动后就可以连上注册中心把自己注册上去,这过程就是服务注册。每个微服务,比如商品服务都应该注册…...

c语言函数学习

C语言函数学习笔记&#xff1a;从入门到实践 一、什么是函数&#xff1f; 函数是C语言中用于封装特定功能的代码块&#xff0c;是模块化编程的核心。通过函数可以实现&#xff1a; 代码复用&#xff1a;避免重复编写相同逻辑 逻辑清晰&#xff1a;将复杂程序分解为多个小模块…...

linux利用nfs服务器,实现数据和windows环境拷贝

1. 在Linux上设置NFS服务器 1.1 安装NFS服务器软件 首先&#xff0c;你需要在Linux服务器上安装NFS服务器软件。假设你使用的是基于Debian的系统&#xff08;如Ubuntu&#xff09;&#xff0c;可以按照以下步骤操作&#xff1a; sudo apt update sudo apt install nfs-kerne…...

智能理解 PPT 内容,快速生成讲解视频

当我们想根据一版 PPT 制作出相对应的解锁视频时&#xff0c;从撰写解锁词&#xff0c;录制音频到剪辑视频&#xff0c;每一个环节都需要投入大量的时间和精力&#xff0c;本方案将依托于阿里云函数计算 FC 和百炼模型服务&#xff0c;实现从 PPT 到视频的全自动转换&#xff0…...

FFmpeg + OpenGL ES 美颜相机教程大纲

做OpenGL和FFmpeg也有很长一段时间了&#xff0c;最近打算结合FFmpegOpenGL ES做一期视频教程&#xff0c;下面是完整视频教程大纲。最终的项目实战效果是实现一款美颜相机。教程分为理论讲解和实战开发两部分&#xff0c;适合有一定编程基础的开发者。课程计划是免费发布在B站…...