volatile关键字和内存/读写屏障的深入理解

news/2024/11/26 6:00:56/

        大家都知道volatile关键字是在多线程学习中非常关键的存在,可以保证一个变量在多线程中是一直可见的,好像刚学习的时候只知道这些,但其中的原理远不止于此。原理其实就是标题里已经说明的读写屏障。

        先讲一下volatile关键字的作用,众所周知,volatile是一个类型修饰符,用于修饰变量。它主要用于确保变量的可见性和防止指令重排序。当一个变量被声明为volatile时,多个线程对这个变量进行访问时,每个线程都会读取变量的最新值,而不是使用线程本地缓存中的副本。这就保证了不同线程对该变量的操作的可见性。

        那他是怎么实现可见性和防止指令重排序的呢,这两个特性看似根本不相干啊,这是我刚学这个知识点以及学了好几遍之后还是这种看法,到我真正明白这个原理的时候才恍然大悟。先透彻的分析一遍原理,内存屏障也就是读写屏障,分为读屏障和写屏障,解释一下定义:内存屏障(Memory Barrier)是一种硬件或软件层面的机制,用于控制处理器对内存操作的顺序,确保特定的操作按照预期的顺序执行。它主要是为了解决多处理器系统中的内存一致性问题。

        简单来说,cpu内缓存和内存的关系就类似于应用层里的redis和DB的关系,在多线程情况下,默认取数据的时候都是从redis(缓存)里取,只有线程结束时才会写回DB(内存),这时,当A线程进行了修改一个变量但线程未结束,B线程如果不停需要根据这个变量计算结果,这是就会出现常见的问题,原理也就是这个:缓存还未写回内存。

        利用应用层的思想直接做缓存同步不就行了,这还不太一样,我们开发中可以直接读数据库(内存)也可以直接读缓存,但是在硬件方面只能直接读缓存。所以只能考虑缓存和内存间的同步问题,volatile对这个变量进行了一种封装,当这个变量写入的时候给他加写屏障,读这个变量的时候加读屏障,写屏障简单理解就是把(所有)缓存里的数据直接push到内存中,类似于事务,A事务和B事务谁先开始无所谓,决定执行顺序的是谁先提交,就是这个道理,这个写操作代码先push进去了,代表之前的写操作的代码也一并push进去了,肯定可以保障后面的代码无法重排到写操作之前的代码。读屏障也一个道理,把内存里的(所有)数据给pull到线程缓存中,这样不仅实现了有序性又实现了可见性。

        杂谈:这种设计对吗,当然是对的,但是就一定好吗,我感觉对于开发来说也许有失偏颇,不仅让代码变得复杂而且两种无论是相同的特性即使是毫无相关,分开也远比合在一起好得多,有一种偏锋的感觉。


http://www.ppmy.cn/news/1549995.html

相关文章

PCA 主成分分析算法

PCA 算法的目的是降纬,多维数据分析时无法进行表达,在数据分析中,常用的是两个变量,也就是二维坐标系进行数据分析。PCA 可以将多维数据进行主成分析,从而达到降维的目的,最终使用 PCA 中的 PC1 和 PC2 作为…

sd webui整合包怎么安装comfyui

环境: sd webui整合包 comfyui 问题描述: sd webui整合包怎么安装comfyui 扩展安装不成功 解决方案: 1.直接下载 ,解压到SD文件夹里(或者git拉一下) 2.ComfyUI模型共享:如果本机部署过Webui,那么ComfyUI可以与WebUI公用一套模型,防止复制大量模型浪费空间 将…

【小白学机器学习33】 大数定律python的 pandas.Dataframe 和 pandas.Series基础内容

目录 0 总结 0.1pd.Dataframe有一个比较麻烦琐碎的地方,就是引号 和括号 0.2 pd.Dataframe关于括号的原则 0.3 分清楚几个数据类型和对应的方法的范围 0.4 几个数据结构的构造关系 list → np.array(list) → pd.Series(np.array)/pd.Dataframe 1 python 里…

一篇文章学会功能测试(手工测试)

目录 **幕布思维导图链接:https://www.mubu.com/doc/48eF6fpTR9s**面试项目介绍项目的作用项目的用户群体项目的业务,模块项目中使用到的技术 项目测试流程测试流程何时开始执行用例执行方式执行结果记录 测试方法业务测试测试方法测试用例编写流程为什么…

Oracle 数据库 IDENTITY 列

IDENTITY列是Oracle数据库12c推出的新特性。之所以叫IDENTITY列,是由于其支持ANSI SQL 关键字 IDENTITY,其内部实现还是使用SEQUENCE。 不过推出这个新语法也是应该的,毕竟MyQL已经有 AUTO_INCREMENT列,而SQL Server也已经有IDENT…

autogen框架中使用chatglm4模型实现react

本文将介绍如何使用使用chatglm4实现react,利用环境变量、Tavily API和ReAct代理模式来回答用户提出的问题。 环境变量 首先,我们需要加载环境变量。这可以通过使用dotenv库来实现。 from dotenv import load_dotenv_ load_dotenv()注意.env文件处于…

C语言-数学基础问题

一.奇数、偶数问题 1.从键盘上输入一个整数,判断并输出它是奇数还是偶数。 //从键盘上输入一个整数,判断并输出它是奇数还是偶数。 main() {int i;printf("输入一个整数:\n");scanf("%d",&i);if(i%20)printf("它是偶数\n…

使用 OpenCV 进行视频中的行人检测

在计算机视觉领域,行人检测是一个重要的研究方向,它在视频监控、自动驾驶、人机交互等领域都有着广泛的应用。本文将介绍如何使用 OpenCV 库来实现视频中的行人检测。 环境准备 首先,我们需要安装 OpenCV 库。可以通过以下命令来安装&#…