当前位置: 首页 > 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最先进的代…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

Leetcode 3576. Transform Array to All Equal Elements

Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接&#xff1a;3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到&#xf…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

智慧工地云平台源码,基于微服务架构+Java+Spring Cloud +UniApp +MySql

智慧工地管理云平台系统&#xff0c;智慧工地全套源码&#xff0c;java版智慧工地源码&#xff0c;支持PC端、大屏端、移动端。 智慧工地聚焦建筑行业的市场需求&#xff0c;提供“平台网络终端”的整体解决方案&#xff0c;提供劳务管理、视频管理、智能监测、绿色施工、安全管…...

在Ubuntu中设置开机自动运行(sudo)指令的指南

在Ubuntu系统中&#xff0c;有时需要在系统启动时自动执行某些命令&#xff0c;特别是需要 sudo权限的指令。为了实现这一功能&#xff0c;可以使用多种方法&#xff0c;包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法&#xff0c;并提供…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

力扣-35.搜索插入位置

题目描述 给定一个排序数组和一个目标值&#xff0c;在数组中找到目标值&#xff0c;并返回其索引。如果目标值不存在于数组中&#xff0c;返回它将会被按顺序插入的位置。 请必须使用时间复杂度为 O(log n) 的算法。 class Solution {public int searchInsert(int[] nums, …...

Reasoning over Uncertain Text by Generative Large Language Models

https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

python报错No module named ‘tensorflow.keras‘

是由于不同版本的tensorflow下的keras所在的路径不同&#xff0c;结合所安装的tensorflow的目录结构修改from语句即可。 原语句&#xff1a; from tensorflow.keras.layers import Conv1D, MaxPooling1D, LSTM, Dense 修改后&#xff1a; from tensorflow.python.keras.lay…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...