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

[知识点] 内存顺序属性的用途和行为

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

1. std::memory_order_relaxed

  • 定义:不提供同步或顺序保证,只保证原子操作本身的原子性。
  • 用途:适用于不需要同步的情况下,用于计数器等场景。
  • 行为:操作之间可以自由重排序,其他线程可能看到不同的操作顺序。
#include <atomic>
#include <iostream>
#include <thread>// 计数器,用于多线程递增
std::atomic<int> counter(0);void increment() {for (int i = 0; i < 1000; ++i) {// 使用 memory_order_relaxed 进行原子加操作// 不保证任何顺序,只保证原子性counter.fetch_add(1, std::memory_order_relaxed);}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();// 输出最终的计数器值std::cout << "Counter: " << counter.load(std::memory_order_relaxed) << std::endl;return 0;
}

2. std::memory_order_consume

  • 定义:专用于指针依赖的消费操作,确保后续依赖操作的顺序。
  • 用途:用于消费操作,确保依赖指针的操作不会被重排序到消费操作之前
  • 行为:类似于 memory_order_acquire,但仅保证指针依赖的顺序。
#include <atomic>
#include <iostream>
#include <thread>// 原子指针,指向整数数据
std::atomic<int*> p;
int data;void producer() {data = 42;// 使用 memory_order_release 存储指针// 确保 data 的写入在存储指针之前完成p.store(&data, std::memory_order_release);
}void consumer() {int* ptr;// 使用 memory_order_consume 加载指针// 确保指针依赖的操作不会被重排序while (!(ptr = p.load(std::memory_order_consume)));// 输出指针指向的数据std::cout << "Data: " << *ptr << std::endl;
}int main() {std::thread t1(producer);std::thread t2(consumer);t1.join();t2.join();return 0;
}

3. std::memory_order_acquire

  • 定义:获取操作,确保后续读写操作不会被重排序到获取操作之前
  • 用途:用于加载操作,以确保加载后的操作看到的是最新的数据
  • 行为:获取操作之前的读写操作可能被重排序,但之后的操作不会
#include <atomic>
#include <iostream>
#include <thread>// 标志变量,用于同步
std::atomic<int> flag(0);
int data = 0;void writer() {data = 42;// 使用 memory_order_release 存储标志// 确保 data 的写入在存储标志之前完成flag.store(1, std::memory_order_release);
}void reader() {// 使用 memory_order_acquire 加载标志// 确保标志被加载后,读取 data 的操作不会被重排序while (flag.load(std::memory_order_acquire) != 1);// 输出 data 的值std::cout << "Data: " << data << std::endl;
}int main() {std::thread t1(writer);std::thread t2(reader);t1.join();t2.join();return 0;
}

4. std::memory_order_release

  • 定义:释放操作,确保之前的读写操作不会被重排序到释放操作之后。
  • 用途:用于存储操作,以确保存储前的所有操作完成。
  • 行为:释放操作之后的读写操作可能被重排序,但之前的操作不会。
#include <atomic>
#include <iostream>
#include <thread>// 标志变量,用于同步
std::atomic<int> flag(0);
int data = 0;void writer() {data = 42;// 使用 memory_order_release 存储标志// 确保 data 的写入在存储标志之前完成flag.store(1, std::memory_order_release);
}void reader() {// 使用 memory_order_acquire 加载标志// 确保标志被加载后,读取 data 的操作不会被重排序while (flag.load(std::memory_order_acquire) != 1);// 输出 data 的值std::cout << "Data: " << data << std::endl;
}int main() {std::thread t1(writer);std::thread t2(reader);t1.join();t2.join();return 0;
}

5. std::memory_order_acq_rel

  • 定义:获取和释放操作的组合,适用于读-修改-写操作。
  • 用途:用于原子操作,如 compare_exchange,以确保操作的前后都不会被重排序。
  • 行为:操作之前和之后的读写操作都不会被重排序。
#include <atomic>
#include <iostream>
#include <thread>// 原子计数器,用于多线程递增
std::atomic<int> counter(0);void increment() {for (int i = 0; i < 1000; ++i) {int expected = counter.load(std::memory_order_relaxed);// 使用 memory_order_acq_rel 进行比较并交换操作// 确保操作之前和之后的读写顺序while (!counter.compare_exchange_weak(expected, expected + 1, std::memory_order_acq_rel));}
}int main() {std::thread t1(increment);std::thread t2(increment);t1.join();t2.join();// 输出最终的计数器值std::cout << "Counter: " << counter.load(std::memory_order_relaxed) << std::endl;return 0;
}

6. std::memory_order_seq_cst

  • 定义:获取和释放操作的组合,适用于读-修改-写操作。
  • 用途:用于原子操作,如 compare_exchange,以确保操作的前后都不会被重排序。
  • 行为:操作之前和之后的读写操作都不会被重排序。
#include <atomic>
#include <iostream>
#include <thread>// 原子变量
std::atomic<int> x(0), y(0);
int r1, r2;void thread1() {// 使用 memory_order_seq_cst 存储 x// 确保全局顺序一致x.store(1, std::memory_order_seq_cst);// 使用 memory_order_seq_cst 加载 y// 确保全局顺序一致r1 = y.load(std::memory_order_seq_cst);
}void thread2() {// 使用 memory_order_seq_cst 存储 y// 确保全局顺序一致y.store(1, std::memory_order_seq_cst);// 使用 memory_order_seq_cst 加载 x// 确保全局顺序一致r2 = x.load(std::memory_order_seq_cst);
}int main() {std::thread t1(thread1);std::thread t2(thread2);t1.join();t2.join();// 输出结果std::cout << "r1: " << r1 << ", r2: " << r2 << std::endl;return 0;
}

总结

  • std::memory_order_relaxed: 最弱的同步和顺序保证,仅保证原子操作本身的原子性。
  • std::memory_order_consume: 专用于指针依赖,确保后续依赖操作的顺序。
  • std::memory_order_acquire: 获取操作,确保后续读写操作不会被重排序到获取操作之前。
  • std::memory_order_release: 释放操作,确保之前的读写操作不会被重排序到释放操作之后。
  • std::memory_order_acq_rel: 获取和释放操作的组合,适用于读-修改-写操作。
  • std::memory_order_seq_cst: 顺序一致性操作,提供最强的同步和顺序保证。

相关文章:

[知识点] 内存顺序属性的用途和行为

C标准库中定义了以下几种内存顺序属性&#xff1a; std::memory_order_relaxedstd::memory_order_consumestd::memory_order_acquirestd::memory_order_releasestd::memory_order_acq_relstd::memory_order_seq_cst 1. std::memory_order_relaxed 定义&#xff1a;不提供同步…...

JAVA Mongodb 深入学习(二)索引的创建和优化

一、常用索引类型 1、单个索引 单个索引的创建 db.你的表名.createIndex({"你的字段名":1}) 单个索引的创建且是唯一索引 db.你的表名.createIndex({"你的字段名":1}),{ unique: true }) 2、复合索引 将多个过滤的字段&#xff0c;做成索引&#xff0c;…...

转让北京劳务分包地基基础施工资质条件和流程

地基基础资质转让流程是怎样的?对于企业来说&#xff0c;资质证书不仅是实力的证明&#xff0c;更是获得工程承包的前提。而在有了资质证书后&#xff0c;企业才可以安心的准备工程投标&#xff0c;进而在工程竣工后获得收益。而对于从事地基基础工程施工的企业&#xff0c;需…...

Python基础——字符串

一、Python的字符串简介 Python中的字符串是一种计算机程序中常用的数据类型【可将字符串看作是一个由字母、数字、符号组成的序列容器】&#xff0c;字符串可以用来表示文本数据。 通常使用一对英文的单引号&#xff08;&#xff09;或者双引号&#xff08;"&#xff09;…...

AP的数据库性能到底重要吗?

先说结论&#xff1a;没那么重要。甚至可能不重要。 我用我的经历和分析给大家说说。诸位看看如何。 不重要的观点是不是不能接受&#xff1f; 因为这些是站在我们角度觉得的。而实际上使用者&#xff08;业务或者用户&#xff09;&#xff0c;真的不太在乎我们所在乎的。 …...

Vue3【二】 VSCode需要安装的Vue语法插件

VSCode需要安装的 适配Vue3的插件 Vue-Official插件安装...

设置路径别名

一、描述 如果想要给路径设置为别名&#xff0c;就是常见的有些项目前面的引入文件通过开头的&#xff0c;也就是替换了一些固定的文件路径&#xff0c;怎么配置。 二、配置 import { defineConfig } from vite import react from vitejs/plugin-react import path from path…...

人事信息管理系统(Java+MySQL)

一、项目背景 在现代企业中&#xff0c;管理大量员工的工作信息、薪资、请假、离职等事务是一项非常繁琐和复杂的任务。传统的手工管理方式不仅效率低下&#xff0c;而且容易出错。为了提高人事管理的效率&#xff0c;减少人工操作带来的错误&#xff0c;企业迫切需要一个高效…...

Python 中生成器与普通函数的区别

在Python中&#xff0c;生成器和普通函数有一些区别。 生成器使用 yield 语句从函数中返回一个值&#xff0c;而不是使用 return 语句。当生成器函数被调用时&#xff0c;它会返回一个迭代器对象&#xff0c;而非立即执行函数体内的代码。 生成器函数可以通过多次调用 yield 语…...

最小栈、栈的弹出(C++)

1.最小栈 思路分析&#xff1a; 代码&#xff1a; class MinStack { public:MinStack() {}void push(int val) {st.push(val);//两种情况需要更新最小值//1.最小栈为空(就是存最小值的那个栈)//2.插入的值小于或等于最小栈的栈顶元素if(minstack.empty()||minstack.top()>…...

20240607每日通信--------VUE3前端引入scoket-io,后端引入Netty-SocketIO,我成功了,希望一起交流沟通

无语 前置&#xff1a; VUE3 前端集成scoket-io socket.io-client Sringboot 3.0JDK17集成Netty-SocketIO Netty-SocketIO 失败原因一&#xff1a; 前期决定要写demo时候&#xff0c;单独了解了&#xff0c;后端引入Netty-SocketIO注意事项&#xff0c;详见我先头写的博客 前…...

Tomcat源码解析(八):一个请求的执行流程(附Tomcat整体总结)

Tomcat源码系列文章 Tomcat源码解析(一)&#xff1a;Tomcat整体架构 Tomcat源码解析(二)&#xff1a;Bootstrap和Catalina Tomcat源码解析(三)&#xff1a;LifeCycle生命周期管理 Tomcat源码解析(四)&#xff1a;StandardServer和StandardService Tomcat源码解析(五)&…...

python使用gdb进行堆栈查看与调试

以ubuntu示例&#xff0c;先安装gdb与python-dbg&#xff0c;dbg按照python版本安装 apt install -y gdb python3.10-dbg 使用top查看python进程&#xff0c;使用gdb操作python进程 gdb python3 6618 加载环境 source /usr/share/gdb/auto-load/usr/bin/python3.10-gdb.py…...

【DevOps】路由与路由器详细介绍:原理、功能、类型及应用场景

目录 一、路由详细介绍 1、什么是路由&#xff1f; 2、路由的基本原理 3、 路由协议 静态路由 动态路由 4、 路由表 5、 路由算法 6、路由的优缺点 优点 缺点 7、 路由应用场景 二、路由器详细介绍 1、什么是路由器&#xff1f; 2、 路由器的工作原理 3、路由器…...

【WP|9】深入解析WordPress [add_shortcode]函数

add_shortcode 是 WordPress 中一个非常强大的函数&#xff0c;用于创建自定义的短代码&#xff08;shortcodes&#xff09;。短代码是一种简洁的方式&#xff0c;允许用户在内容中插入动态的、可重用的功能。通过 add_shortcode&#xff0c;开发者可以定义自己的短代码&#x…...

Qt QStackedWidget类详细分析

一.定义 QStackedWidget类是一个容器控件&#xff0c;它提供了一个堆叠的页面布局方式&#xff0c;每个页面可以包含一个子部件。在QStackedWidget中&#xff0c;只有当前活动的页面是可见的&#xff0c;其他页面会被隐藏起来。 QStackedWidget类的常用方法包括&#xff1a; a…...

Java数据结构与算法(leetcode热题881. 救生艇)

前言 救生艇属于贪心算法&#xff0c;解题之前条件一定要归纳好。题目中存在3个要求&#xff1a; 1.一艘船最多坐2人 2.船数要求最小 3.每艘船重量小于limit 意味着体重较轻的两人可以同乘一艘救生艇。 . - 力扣&#xff08;LeetCode&#xff09; 实现原理 1.重量大的有…...

react+wijmo所遇问题

1.官网地址&#xff1a;https://demo.mescius/wijmo/demos/Grid/Overview/react 别进中文地址&#xff0c;注意后缀mescius有没有.cn有的话删掉&#xff0c;那个没有触发方法和各类API&#xff0c;组件也不全 2.中文地址&#xff1a;&#xff08;不太好用&#xff09;&#x…...

手撕设计模式——克隆对象之原型模式

1.业务需求 ​ 大家好&#xff0c;我是菠菜啊&#xff0c;前俩天有点忙&#xff0c;今天继续更新了。今天给大家介绍克隆对象——原型模式。老规矩&#xff0c;在介绍这期之前&#xff0c;我们先来看看这样的需求&#xff1a;《西游记》中每次孙悟空拔出一撮猴毛吹一下&#x…...

LangChain基础知识入门

LangChain的介绍和入门 1 什么是LangChain LangChain由 Harrison Chase 创建于2022年10月&#xff0c;它是围绕LLMs&#xff08;大语言模型&#xff09;建立的一个框架&#xff0c;LLMs使用机器学习算法和海量数据来分析和理解自然语言&#xff0c;GPT3.5、GPT4是LLMs最先进的代…...

Oracle查询表空间大小

1 查询数据库中所有的表空间以及表空间所占空间的大小 SELECTtablespace_name,sum( bytes ) / 1024 / 1024 FROMdba_data_files GROUP BYtablespace_name; 2 Oracle查询表空间大小及每个表所占空间的大小 SELECTtablespace_name,file_id,file_name,round( bytes / ( 1024 …...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统

目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索&#xff08;基于物理空间 广播范围&#xff09;2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

苹果AI眼镜:从“工具”到“社交姿态”的范式革命——重新定义AI交互入口的未来机会

在2025年的AI硬件浪潮中,苹果AI眼镜(Apple Glasses)正在引发一场关于“人机交互形态”的深度思考。它并非简单地替代AirPods或Apple Watch,而是开辟了一个全新的、日常可接受的AI入口。其核心价值不在于功能的堆叠,而在于如何通过形态设计打破社交壁垒,成为用户“全天佩戴…...

Python 训练营打卡 Day 47

注意力热力图可视化 在day 46代码的基础上&#xff0c;对比不同卷积层热力图可视化的结果 import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets, transforms from torch.utils.data import DataLoader import matplotlib.pypl…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...

加密通信 + 行为分析:运营商行业安全防御体系重构

在数字经济蓬勃发展的时代&#xff0c;运营商作为信息通信网络的核心枢纽&#xff0c;承载着海量用户数据与关键业务传输&#xff0c;其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级&#xff0c;传统安全防护体系逐渐暴露出局限性&a…...

STM32标准库-ADC数模转换器

文章目录 一、ADC1.1简介1. 2逐次逼近型ADC1.3ADC框图1.4ADC基本结构1.4.1 信号 “上车点”&#xff1a;输入模块&#xff08;GPIO、温度、V_REFINT&#xff09;1.4.2 信号 “调度站”&#xff1a;多路开关1.4.3 信号 “加工厂”&#xff1a;ADC 转换器&#xff08;规则组 注入…...

02-性能方案设计

需求分析与测试设计 根据具体的性能测试需求&#xff0c;确定测试类型&#xff0c;以及压测的模块(web/mysql/redis/系统整体)前期要与相关人员充分沟通&#xff0c;初步确定压测方案及具体的性能指标QA完成性能测试设计后&#xff0c;需产出测试方案文档发送邮件到项目组&…...