详解volatile 关键字

volatile关键字原理的使用介绍和底层原理解析和使用实例 volatile的定义及作用:可见性、有序性和禁止优化。volatile的底层实现原理:JMM、缓存一致性协议和内存屏障。volatile的使用实例:双重检查锁定和中断机制等。如何解决volatile的原子性问题:使用synchronized和Atomic类。AtomicStampedReference用法和ABA问题解决。一些volatile的最佳实践。使用volatile和锁实现的一个简单线程安全容器。 阅读详情

一、前言

1. 编译器优化介绍

  • 硬件优化:

    • 内存访问速度低于 CPU 处理速度,使用硬件高速缓存(Cache)加速内存访问。
    • 现代 CPU 指令可以乱序执行,以充分利用指令流水线,提高执行速度。
  • 软件优化:

    • 程序员优化:在编写代码时进行优化。
    • 编译器优化:
      • 将内存变量缓存到寄存器。
      • 调整指令顺序,充分利用 CPU 指令流水线,如重新排序读写指令。
      • 对常规内存进行优化时,这些优化通常是透明且高效的。
  • 内存屏障:

    • 解决编译器优化或硬件重新排序引起的问题。
    • 内存屏障确保特定顺序执行的操作之间的顺序性。
    • Linux 提供了一个宏函数 void Barrier(void),通知编译器插入一个内存屏障(仅对编译器有效,对硬件无效)。

2. volatile 关键字

  • 数据流分析:
    • 编译器技术,通过分析程序中变量的赋值、使用和失效位置,进行常量合并、传播等优化。
    • 有时这些优化不符合程序需求,此时使用 volatile 关键字禁止这些优化。

二、volatile 详解

1. volatile 的定义和作用

  • 定义:“易变的”。
  • 作用:
    • 编译器通常通过减少内存访问来优化性能,但这可能会导致读取脏数据。
    • 使用 volatile 声明的变量,每次访问都重新从内存读取数据。
    • 禁止编译器对访问 volatile 变量的代码进行优化,确保对特殊地址的稳定访问。

2. 例子解析

1. 禁止编译器优化

int *ip = ...; //设备地址
*ip = 1; //第一个指令
*ip = 2; //第二个指

  • 编译器优化后可能变为:

int *ip = ...;
*ip = 2;

  • 使用 volatile 禁止优化:

volatile int *ip = ...;
*ip = 1;
*ip = 2;

2. volatile 变量每次都从内存读取

volatile char a;
a = 0;
while (!a) {
    // do some things;
}
doother();

  • 如果没有 volatile,doother() 可能不会被执行。

3. volatile 变量的使用场景

1. 中断服务程序修改的变量

static int i = 0;
int main(void) {
    ...
    while (1) {
        if (i) dosomething();
    }
}

void ISR_2(void) {
    i = 1;
}

 

  • i 需要用 volatile 修饰,确保在中断服务程序修改时,主程序能正确读取。
2. 多任务环境下共享的标志
  • 多任务间共享的标志变量需要加 volatile 修饰。
3. 存储器映射的硬件寄存器
volatile int *output = (volatile unsigned int *)0xff800000;
int init(void) {
    int i;
    for (i = 0; i < 10; i++) {
        *output = i;
    }
}
  • 对外部设备初始化时,需要 volatile 确保每次对寄存器的写操作都生效。

4. 常见问题

1. const 和 volatile 同时使用
  • 可以,例如只读的状态寄存器:
    const volatile int status;
    
2. volatile 指针
  • 可以,当中断服务程序修改指向缓冲区的指针时:
    const volatile int status;
    

5. volatile 的本质

1. 编译器优化
  • 为提高存取速度,编译器可能将变量缓存到寄存器中。
  • volatile 禁止这种优化,确保每次都从原始内存地址读取变量。
2. 解释
  • volatile 应解释为“直接存取原始内存地址”。

6. 函数示例

错误示例
int square(volatile int *ptr) {
    return *ptr * *ptr;
}
  • 可能导致错误,因为 *ptr 的值可能在两次读取之间改变。
正确示例
long square(volatile int *ptr) {
    int a;
    a = *ptr;
    return a * a;
}

注意事项

  • 频繁使用 volatile 可能增加代码尺寸并降低性能,因此应合理使用。
Linux C中多线程与volatile变量 主要介绍了Linux C中多线程与volatile变量的相关资料,需要的朋友可以参考下 立即下载

相关推荐

【个人记录】CentOS7升级glibc至2.28

由于CentOS7系统已经停止支持, 虽然大部分业务已经迁移至OpenEuler,但仍然有部分业务系统跑在CentOS7上。在尝试部署新业务环境时经常会提示如下错误(以code-server运行需要的node 20为例)node -v为了保障业务可正常运行,通常采用Docker继承好的node环境进行部署,但部分场景还是需要宿主机使用新版glibc版本。本文记录本人一次成功升级glibc(2.17=>2.28)的步骤。

喵呜 3883

【Linux】再次理解volatile 关键字

volatile的作用:保存内存可见性 这个关键字我们在C语言中已经有所涉猎,今天我们站在信号的角度重新理解一下。 首先看下面的代码: #include <stdio.h> #include <signal.h> #include <unistd.h> int flag=0; void sighandler(int sig) { printf("chang...

ly_6699的博客 496

智能车竞赛飞檐走壁组立体赛道电磁引导线设计与实现

本文深入解析了智能车竞赛飞檐走壁组立体赛道电磁引导线的核心设计与实现。针对垂直面、圆筒、跷跷板等立体元素,详细阐述了电磁线规格参数选择、三维空间铺设技巧及磁场调试方法,旨在帮助参赛队伍打造稳定可靠的导航系统,提升车模在复杂立体赛道上的通过率与稳定性。

bert9linguist的博客 280

linux volatile,深入理解volatile关键字

关于volatile关键字的话,工作中没有遇到使用场景,大部分是面试的时候必问的一个题目;本文主要内容摘自《Java高并发编程详解》1. CPU Cache模型CPU Cache主要是为了解决CPU与内存之间访问速度的差异问题,Cache则是在程序运行的过程中会将运算的所需数据从主内存复制一份到CPU Cache中,这样CPU在计算的过程中,可以直接从CPU Cache中读取或写入,当运算结束之后...

weixin_39949607的博客 482

VS(QT)调用Matlab函数的方法

调试–>窗口–>异常设置–>Win32 Exceptions全部不要勾选。选择Microsoft Visual C++ 2017。将生成的.h和.lib分别放置在对应的文件夹。输入mex -setup C++输入deploytool选择。选择Realse x64。

woshigaowei5146的博客 591

Oracle EBS Interface/API(42) -AP发票客制化付款申请

背景 在OA系统上,选择Oracle EBS的某张AP发票做付款申请,需要类似于锁定该发票以便付款,其他用户或者下次用户不能再次选择该发票做付款申请。 快速参考 参考点 内容 功能导航 N: AP->Invoices->Entry>Invoices 并发请求 None 基表 AP.AP_INV_SELECTION_CRITERIA_ALLAP.AP_SELECTED_INVOICES_ALL API 参考下面介绍 错误信息表 None 接口Form

陈显平的专栏-Oracle EBS 1200

Linux | C语言中volatile关键字的理解

本章主要讲解介绍volatile关键的作用与使用场合;深刻理解volatile关键字;本文你需要有信号相关的基础知识;Linux | 信号-优快云博客。

Nice_W的博客 788

11、体内皮质功能的电压敏感染料成像技术

本文详细介绍了电压敏感染料成像(VSDI)技术在体内皮质功能研究中的应用。内容涵盖VSDI的技术起源、作用机制、信号特点与解读局限性,以及其在映射感觉皮质功能区方面的优势。文章对比了VSDI与电极记录和钙成像技术的差异,突出了其在高时空分辨率下监测神经元群体亚阈值活动的独特价值。同时,提供了完整的实验操作流程,包括手术步骤、染料应用、光学系统配置及数据分析方法,并总结了常见问题及其解决方案。随着基因靶向和多模态技术结合的发展,VSDI有望进一步提升信号特异性和空间精度,成为解析大脑网络动态的重要工具。

Apple的专栏 81

volatile关键字(Linux环境下了解)

volatile关键字告诉编译器不要优化自己所修饰的变量(主要是解决优化产生的问题)

challenglistic的博客 853

基于深度学习的三维重建算法——详解与实现

随着深度学习技术的迅猛发展,基于深度学习的三维重建算法在最近几年取得了显著的进展。而基于深度学习的三维重建算法通过利用深度神经网络,能够从大规模数据中学习到更准确、鲁棒的三维结构表示。本文综述了基于深度学习的三维重建算法,并给出了相应的源代码。随着深度学习技术的不断发展,我们相信基于深度学习的三维重建算法将会在未来得到更广泛的应用。实验结果表明,基于深度学习的三维重建算法在准确性和鲁棒性方面取得了显著的提升。以上是关于基于深度学习的三维重建算法的详细介绍与实现,希望对您有所帮助。

CyberGenius的博客 1227

基于Simulink的异步电机定子磁链定向控制(SFOC)仿真

本文带你从零构建了异步电机SFOC系统​ 的完整Simulink仿真模型,实现了:✅ 搭建异步电机、逆变器、风机负载的主电路与传感器模型;✅ 用MATLAB Function实现定子磁链观测(电压模型)、坐标变换、双闭环PI控制;✅ 验证SFOC在转速跟踪(响应0.2s、超调4%)、转矩响应(恢复0.15s)中的高性能;✅ 对比RFOC,明确SFOC在参数鲁棒性(转子电阻+50%时波动<2%)上的独特优势;✅ 理解SFOC“定子磁链定向+解耦控制”的核心思想(低成本高鲁棒性驱动的工程实现)。

xiaoheshang_123的博客 389

volatile关键字详解

volatile关键字1.volatile简介:2.三大特性1>.保证可见性:代码验证:2>.保证有序性(禁止指令重排序)有序性的实现原理:3>.不保证原子性:解决方式: 1.volatile简介: volatile 是 JVM 提供的轻量级的同步机制。volatile 关键字可以保证并发编程三大特征(原子性、可见性、有序性)中的可见性和有序性,不能保证原子性。 2.三大特性 1>.保证可见性: 加了volatile关键字修饰的变量,只要有一个线程将主内存中的变量值做了修改,其他线程

LYQ20010417的博客 1万+

Z-Image Turbo随机性增强插件的下载教程及使用方法 z-image生成图像太相似怎么办 Z-Image Turbo 整合包下载

Z-Image Turbo 是出了名的“seed 不敏感”,非常难做多样化图像创作。ComfyUi-ConditioningNoiseInjection 插件通过在conditioning(提示词编码)阶段加入可控噪声,成功解决了 Turbo 随机性不足的问题。它不仅能让 Turbo 产生更丰富的构图差异,还能保持主题稳定,是目前我测试过最有效的 Turbo 随机性增强工具。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 1978

Java并发:volatile关键字详解

重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。

2401_84414763的博客 990

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

java volatile 关键字详解

java volatile 关键字详解 一,什么是volatile关键字,作用是什么 ​ volatile是java虚拟机提供的轻量级同步机制 ​ 作用是: 1.保证可见性 2.禁止指令重排 3.不保证原子性 本篇具体就讲解 什么叫保证了可见性, 什么叫禁止指令重排,什么是原子性 而在这之前需要对JMM 有所了解 二,什么是JMM ​ JMM(java 内存模型 Java Memory Model 简称JMM) 本身是一个抽象的概念,并不在内存中真实存在的,它描述的

clinginh的博客 9724

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

volatile 关键字详解

摘要:Java的volatile关键字解决了多线程环境下的可见性和有序性问题。它确保变量修改立即刷新到主内存,并禁止指令重排序,在单例模式的双重检查锁定中尤为关键。volatile通过内存屏障实现功能,但不同于synchronized,它不保证复合操作的原子性。适用于状态标志、安全发布等场景,但需注意其局限性。现代Java强化了volatile的内存语义,使其成为轻量级线程安全工具,需正确理解其适用场景才能有效使用。

qq_33764173的博客 925

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Volatile关键字详解

原文地址 Java 内存模型的原子性、可见性、有序性基本概念 原子性: 原子是世界上的最小单位,具有不可分割性。比如 a=0;(a非long和double类型)这个操作是不可分割的,那么我们说这个操作时原子操作。再比如:a++; 这个操作实际是a = a +1;是可分割的,所以他不是一个原子操作。非原子操作都会存在线程安全问题,需要我们使用同步技术(sychronized)来让它变成一个原子操作。一个操作是原子操作,那么我们称它具有原子性。java的concurrent包下提供了一些原子类,我们可以通过阅

小灰狼与大白兔的博客 4995
上一篇: 2021-10-15 C语言 函数
下一篇: const的用法(定义和用途)
Raymond430
博客等级 码龄7年 91粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值