C中的volatile用法

C语言中volatile关键字用法 1.1. 编译器的优化介绍 介绍Volatile关键字之前我们先了解一下编译器的优化。 高速缓存:处理器读取程序里面的数据时,把一些访问频率比较高的数据,临时存储到寄存器(register)中,当需要取数据时,就会从 register 中取,而不是直接去从 memory(内存)中取,节约了时间,像这样的过程,叫做高速缓存。 硬件级别的优化:内存访问速度远不及CPU处理速度,为提高机器整体性能,在硬件上引入硬件高速缓存(Cache),加速对内存的访问。另外在现代CPU中指令的执行并不一定严格按照顺序执 阅读详情

volatile 影响编译器编译的结果,指出,volatile 变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化,以免出错,(VC++ 在产生release版可执行码时会进行编译优化,加volatile关键字的变量有关的运算,将不进行编译优化。)。
例如:
volatile int i=10;
int j = i;
...
int k = i;
volatile 告诉编译器i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的可执行码会重新从i的地址读取数据放在k中。
而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在k中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问,不会出错。

/**********************

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:
1) 并行设备的硬件寄存器(如:状态寄存器)
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3) 多线程应用中被几个任务共享的变量
回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、中断、RTOS等等打交道,所有这些都要求用到volatile变量。不懂得volatile的内容将会带来灾难。假设被面试者正确地回答了这是问题(嗯,怀疑是否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。
1)一个参数既可以是const还可以是volatile吗?解释为什么。
2); 一个指针可以是volatile 吗?解释为什么。
3); 下面的函数有什么错误:
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
下面是答案:
1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。
2); 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。
3) 这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
位操作(Bit manipulation)

//*********************

嵌入式编程中经常用到 volatile这个关键字,在网上查了下他的用法可以归结为以下两点:

一:告诉compiler不能做任何优化

   比如要往某一地址送两指令:
   int *ip =...; //设备地址
   *ip = 1; //第一个指令
   *ip = 2; //第二个指令
   以上程序compiler可能做优化而成:
   int *ip = ...;
   *ip = 2;
   结果第一个指令丢失。如果用volatile, compiler就不允许做任何的优化,从而保证程序的原意:
   volatile int *ip = ...;
   *ip = 1;
   *ip = 2;
   即使你要compiler做优化,它也不会把两次付值语句间化为一。它只能做其它的优化。这对device driver程序员很有用。

二:表示用volatile定义的变量会在程序外被改变,每次都必须从内存中读取,而不能把他放在cache或寄存器中重复使用。

   如   volatile char a;  
        a=0;
       while(!a){
//do some things;  
       }  
       doother();
   如果没有 volatile doother()不会被执行

linux C 中的volatile使用 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子:      1). 并行设备的硬件寄存器(如:状态寄存器)      2). 一个中断服务子程序中会访问到的非自动变量(Non-automatic 阅读详情

相关推荐

什么是 C 语言中的 volatile 关键字?

volatile关键字在 C 语言中是一个重要的工具,用于处理那些可能被意外修改或者与硬件、中断、多线程等特殊情况相关的变量。正确使用volatile可以避免由于编译器优化而导致的错误,但也要注意它的局限性,不能将其视为解决多线程同步问题的万能钥匙。在复杂的多线程和并发环境中,还需要结合其他同步机制来确保程序的正确性和稳定性。理解volatile的工作原理和适用场景对于编写可靠的 C 语言程序,特别是在与底层硬件交互和多线程编程方面,是非常重要的。🎉相关推荐📙C 语言百万年薪修炼课程。

2401_86074221的博客 2435

面试题7——一个指针可以是volatile吗?

可以。 因为指针和普通变量一样,有事也有变化程序的不可控性。常见例:子中断服务子程序修改一个指向一个buffer的指针时,必须用volatile来修饰指针。 指针是一种普通的变量,从访问上没有什么不同于其他变量的特性。其保存的数值是个整形数据,和整型变量不同的是,这个整型数据指向的是一段内存地址。 ...

一步两步先生的博客 5557

C语言 const、volatile、const volatile限定符理解

  在C语言经常会用到变量类型限定符const和volatile,但是const和 volatile也可以一起使用。下面就一次分析一下这三种情况的使用方法。 1、const   从字面意思理解,意思就是常量,常数,也就是不能通过赋值、递增、递减来修改它的值。 对于普通变量来说,它的使用很简单。比如定义了一个变量 const int i = 10; 那么在代码中只能使用 i 的值,而不能修改 i 的值。 对于指针来说,它的使用就会稍微复杂一点。 const int *p; 这个意思就是指针 p 指向的

HXYDJ的博客 2286

C语言中voliate关键字的作用

一个变量用voliate关键字修饰,是要告诉编译器,这个变量的值随时可能发生变化,所以编译器每次都必须从变量对应的内存地址中获取该变量的值。 voliate的常用方式:当一个变量表示某寄存器的值时,需要用voliate修饰,这样编译器就不会优化,所谓优化,就是每次去读取寄存器里面的数据,作为这个变量的值,问题在于,如果程序中已经改变了该变量的值,那么就会导致这个变量值跟寄存器里面的值不一样,从而导致冲突,用voliate就会避免这个问题,因为不会再去寄存器读取数据作为该变量的值了,而是直接去变量对应的内存地

七度使徒的博客 1万+

c语言volatile 的用法总结

1,我们在开发过程中经常看看valatile关键字的使用,我们今天就来总结一下这个关键字的使用吧!

陌上花开缓缓归以的博客 1518

volatile在C语言中的基本使用方法

实际上,你可以把寄存器eax当做busy所在内存的cache,当cache(寄存器)和内存中的数据一致时不会有任何问题,但当cache与内存中的数据不一致时(也就是内存已被更新但cache保存的还是旧数据),程序的运行往往出乎预料。A线程读取busy变量,B线程更新busy变量,当A检测到busy变化后执行特定操作,这样可行吗?我们知道,由于CPU与内存之间的速度差异非常大,CPU与内存之间有一层cache,CPU其实并没有直接读取内存,cache的存在会让问题复杂起来,限于篇幅与本文主题这里不再展开。..

嵌入式技术开发 5886

[转]C中volatile关键字

volatile 影响编译器编译的结果,指出,volatile 变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化,以免出错,(VC++ 在产生release版可执行码时会进行编译优化,加volatile关键字的变量有关的运算,将不进行编译优化。)。 例如: volatile int i=10; int j = i; ... int k = i; volatile 告诉编

930

详解C中volatile关键字

一个生动的例子,详解了Volatile关键字对变量的声明在不同编译环境下可能造成不同的结果

C语言关键字之voliate

C语言关键字之voliatevoliate的作用是作为指令关键字,确保本条指令不会因为编译器的优化而省略,而且要求每次从内存中直接读取值当使用voliate 声明变量值时,系统总是重新从它所在的内存读取数据,直接访问变量地址,而编译器对于访问该变量时也不再进行优化voliate关键字影响编译器的结果,用voliate 声明的变量表示该变量随时可能发生变化(因为编译器优化时可能将其放入寄存器中),与...

M_jianjianjiao 1万+

利用DRONEKIT-SITL + MAVPROXY + QGroundControl模拟飞行

dronekit: 一种用于无人机控制的python库。 dronekit-sitl:一种本地仿真工具,相当于本地虚拟化了一个无人机。 mavproxy:数据转发软件(类似于插线板的感觉,一个输入,多个相同的输出)。打开一个Anaconda prompt 首先激活相应的环境 然后运行如下命令: 保持2中的Anaconda prompt处于运行状态,另打开一个Anaconda prompt窗口,运行如下命令: tcp:127.0.0.1:5760: SITL默认端口,作为mavproxy的输入,把输入数据转发

Done___的博客 4344

纽马克-贝塔法(Newmark-Beta Method)在结构动力学中的应用与实现

本文深入解析了纽马克-贝塔法(Newmark-Beta Method)在结构动力学数值计算中的核心原理与应用。作为经典的时间积分算法,它通过调节γ和β参数,在计算精度、稳定性与效率间取得平衡,尤其适用于地震响应、风振分析等工程场景。文章详细阐述了其数学内核、在有限元分析中的实现步骤,并对比了隐式与显式方案的适用场景,为工程师提供了关键的方法选择与参数调优指导。

weixin_29232121的博客 148

C语言中关键字volatile

关键字volatile的理解,作用,使用范围。

m0_67669662的博客 1万+

ZLMediaKit在Windows下启用WebRtc编译(64位)

准备软件 cmake-gui vs2017 已经编译好的windows版本openssl(下载地址) 当然,你完全可以自己按照openssl的官网教程自己编译windows版本的openssl libsrtp编译安装 首先,需要将下载好的openssl解压并添加到环境变量。如下图,将下图路径添加到环境变量 其次,下载libsrtp(下载地址) 下载后解压并新建build文件夹,如下图: 在合适位置新建文件夹放置install后的srtp文件,如"D:\develop20..

byna11sina11的博客 1万+

C语言-volatile

一些编译器允许你把所有的变量隐式的声明为volatile。请抵制这种诱惑,因为它会令你不再思考,当然也会导致生成低效的代码。另外,也不要责怪优化器或直接把它关掉。现代的优化器已经足够优秀,我已经记不清上次遇到优化bug是什么时候了。相反,我常常看到程序员们错误的使用volatile。如果你被要求去修改一个很古怪的代码,请在程序中查找一下volatile关键字;如果你什么也没有找到,上面讨论的例子可以向你提供一些解决问题的思路。这个也顺便说一下哦。

whaosoft143ai的博客 9990

SAP_MM/CO模块-超详细的CK11N/CK40N取值逻辑梳理(十几种业务场景,1.76W字)

本文主要讲述的是三个大的知识点,超详细,涉及到知识点比较多,并且串起来讲解,这也是我在网上搜不到相关资料才自己慢慢研究测试出来的,断断续续耗费了我一周多时间,相信只要你们认真看完,肯定会有所收获; 1、CK11N/CK40N成本发布功能中,系统前台的取数逻辑,涉及到多个采购信息记录、生产版本、货源清单、配额协议等对成本价发布的影响~~!! 2、CK11N与CK40N发布的成本价不一致的问题~~!! 3、如何处理外协加工物料的外协价与BOM组件成本取值不匹配的问题~~!!

风沙的博客 4084

实战干货|.NET9 C#上位机:多PLC并发通信+数据防丢+指令精准下发(10台设备实测+踩坑实录)

摘要:本文介绍了一个基于.NET9重构汽车零部件产线10台西门子S7-1200 PLC并发通信的工业级解决方案。针对原有系统存在的同步轮询阻塞、数据丢失、指令重复等问题,采用连接池复用、异步并发控制、超时隔离等技术,实现800ms内完成10台PLC并发采集、零丢包率、100%指令精准下发。方案通过.NET9的ThreadPool调度优化和ValueTask内存管理,将CPU占用控制在15%以内,解决了多PLC通信中的并发冲突、超时扩散等核心痛点,并提供了可直接复用的工业级代码实现。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 453

C语言中的volatile

关键字volatile有什么含意?并给出三个不同的例子。 一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子: 1) 并行设备的硬件寄存器(如:状态寄存器) 2) 一个中断服务子程序中会访问到的非

JCRunner的专栏 944

用一组可复现实验讲清 ABAP 内表 Standard / Sorted / Hashed 的性能差异

摘要(150字): SAP项目中性能问题常源于ABAP内表选型不当。标准表(STANDARD TABLE)写入快但查找慢(线性扫描),适合遍历场景;排序表(SORTED TABLE)保持有序,支持二分查找,适合范围查询;哈希表(HASHED TABLE)基于唯一键实现常数级查找,适合高频精确匹配。实验表明:标准表+BINARY SEARCH需预排序,成本可能高于直接使用排序表;哈希表在键匹配时性能最优。Gateway和RAP场景中,内表选型直接影响接口响应,建议根据读写负载(追加/遍历/精确查找)选择对应类

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 202

C中的volatile的用法

先占个位置,有空来写。

干一行爱一行 332

2025届程序技术类笔试题

希尔排序在直接插入排序的基础上进行了改进,它通过比较相距一定间隔的元素来进行,各轮比较所用的距离随着算法的进行而减小,直到只比较相邻元素的最后一轮排序为止。某人逆着水流的方向向岸边划船,每次行进前进x米后需要休息一下,休息期间船会自行倒退y米,每次休息后再次行进,前进距离缩短1/5,若起始距离岸边为m米,问:能否到达岸上,需要行进多少次才能上岸。直接插入排序的原理是将第i个元素插入前面i-1个已排好序的记录中,将比第i个元素大的记录依次向后移动一个位置,将第i个元素插入空位。第二轮相邻比较,后移2次。

博客 595

【现代人形机器人:从物理建模到大模型驱动的控制与学习】第1章 机器人建模回顾

本章建立读者进行后续控制 / 优化 / 学习工作的数学与计算基础。内容分为三大块:刚体运动学:位姿表示、坐标变换、旋转参数与李代数/李群(指数映射、twist)多关节机构的正/逆运动学:DH 与 POE 两种建模、雅可比矩阵推导、数值/解析逆解方法与奇异性问题约束动力学:拉格朗日公式、牛顿—欧拉递归算法、接触/冲击模型、受约束系统的方程(拉格朗日乘子与互补性条件)每一节同时给出与练习题。假设读者已具备线性代数(矩阵、特征分解、SVD)、多变量微积分与基础力学(牛顿第二定律)知识。

u012133341的博客 185
上一篇: 求一个字符串s的最大连续递增数字子串
下一篇: iOS视频播放代码
youcanping2008
博客等级 码龄17年 41粉丝 22原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值