volatile

本文深入探讨了volatile关键字的作用机制,解释了它如何避免编译器优化带来的潜在问题,并强调了其在多线程环境中确保变量一致性的重要性。通过实例分析,阐述了volatile与内存、多线程之间的关系,以及正确使用volatile的关键点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.关于 volatile 我觉得这样的解析最容易理解:如果编译器在代码中发现对同一地址的两次访问之间,没有对该地址进行写操作,那么编译器将优化为第一次寻址读该地址时取得的值作为第二次寻址的值,而并不是再做第二次物理上的 I/O 寻址操作。volatile 关键字指示编译器进行强制 I/O 寻址,因为编译器那样的优化,可能并不是我们真正期望的,譬如那个地址上连接着一个传感器上的寄存器,那么实际上,可能该寄存器的值是被传感器自身不断刷新的。因此,我们必要要求CPU每次都进行 I/O 操作。2.Why Use Volatile?The reason to use volatile is to ensure that the compiler generates code to re-load a data item each time it is referenced in your program. Without volatile, the compiler may generate code that merely re-uses the value it already loaded into a register.Volatile advises the compiler that the data may be modified in a manner that may not be determinable by the compiler. This could be, for example, when a pointer is mapped to a device's hardware registers. The device may independently change the values unbeknownst to the compiler.Do you volatile? should you?--by Dr. Kevin P. Dankwardt原文链接 http://www.linuxdevices.com/articles/AT5980346182.html3.volatile 跟以前的 register 相反. register 告诉编译器尽量将变量放到寄存器中使用, 而volatile 强制将更改后的值写回内存(无论是cache还是内存). 如果不写回内存, 对于一些全局共享的变量, 可能导致不一致问题.volatie 只是编译器优化功能的关键字4.volatie变量和cache没有关系,只和内存有关系。简单点说就是每次操作前从内存取值有volatie修饰的变量,每次操作时遵循下面动作:从内存取值 ---> 放入寄存器 ----> 操作 ----> 写回内存没有volatie修饰的变量,操作可能 遵循(可能就是不是所有情况都如此):从内存取值 ---> 放入寄存器 ----> 第一次操作 -----> 第二次操作(此时仍操作寄存器中的值) …… ----> 第N次操作 ----> 写回内存举个例子论述两者关系:int volatie i; //全局变量,在其它地方会被修改while ( i){do_somethings( ) ;}如果i没有被volatie修饰,当while循环执行时,另一段程序并发的执行了i= 0, 这个循环仍不会退出,因为每次循环都是检查寄存器中的值。如果有volatie修饰,那么循环结束,因为循环每次检查i的时候,会先从内存把i读入寄存器,这个时候i在其它地方被赋0,则循环结束。5.这么想就明白了.编译器在进行对源码编译过程中,通常会对反复使用的变量整个逼本到reg当中从而提高访问速度.由volatile声明的变量,实际上就是通知编译器该变量会以你意想不到的方式被更改,所以你丫别优化我. 那么编译器意想不到的方式有哪几种呢,如下:1.Memory map的硬件寄存器(比如). 状态寄存器是最常见, 你想呀, 硬件修改这变量他会告诉编译器嘛, 不会也没这能力, 那编译器不就傻呵呵的把该变量优化了嘛, 一优化就坏事了, 因为我们读到的都是reg中存储的旧的状态寄存器的值, 而非memory当中最新的状态寄存器值. 抄个定义给你看看: #define rIICSTAT (*(volatile unsigned *)0x54000004) //IIC status2.多线程中被几个线程共享的变量. 线程修改共享变量var会通知编译器嘛,不会也没这能力,所以线程A使劲读着var在reg中的副本(狗日的编译器优化),读出来1时他好大展鸿图呀,结果读出来的都是0, 而线程B早就把var变量给修改为1了,怪谁呀,只怪没加volatile,加上volatile不早就读memory当中的var新值1了嘛.3.ISR当中用.这个麻烦,需要拿程序举例,俺就不写了.6.一个gcc-volatile的讨论http://gcc.gnu.org/ml/gcc/2007-10/msg00266.html> If you really want all externally-visible accesses to v to be made exactly> as the code directs, rather than allowing gcc to optimise them in any way that> (from the program's POV) it's just the same 'as-if' they had been done> exactly, make v volatile.That is not enough. Apart from the lack of ISO semantics for volatile,typically a compiler will take volatile as a hint to not holdvalues of the variable in a register.On a multi-processor, this is not enough, because each CPUmay still hold modified values in separate caches.Perhaps gcc actually puts a RW barrier to forcecache synchronisation on every volatile access..this seems rather expensive and very hard to do sinceit is very dependent on the actual box (not just theprocessor). Some processor caches might require externalelectrical signals to synchronise, for example. This isquite possible if you have multiple CPU boards in a box.But I don't actually know what gcc does, although I guessit does nothing. The OS has to do the right thing herewhen a mutex is locked etc, but the code for that isprobably in the kernel which is better able to managethings like cache synchronisation than a compiler.c/c++没有多线程的概念,没有一个明确的memory model,volatile不能保证共享变量在多线称间同步,应该使用明确的lock。

资源下载链接为: https://pan.quark.cn/s/d9ef5828b597 在本文中,我们将探讨如何通过 Vue.js 实现一个带有动画效果的“回到顶部”功能。Vue.js 是一款用于构建用户界面的流行 JavaScript 框架,其组件化和响应式设计让实现这种交互功能变得十分便捷。 首先,我们来分析 HTML 代码。在这个示例中,存在一个 ID 为 back-to-top 的 div 元素,其中包含两个 span 标签,分别显示“回到”和“顶部”文字。该 div 元素绑定了 Vue.js 的 @click 事件处理器 backToTop,用于处理点击事件,同时还绑定了 v-show 指令来控制按钮的显示与隐藏。v-cloak 指令的作用是在 Vue 实例渲染完成之前隐藏该元素,避免出现闪烁现象。 CSS 部分(backTop.css)主要负责样式设计。它首先清除了一些默认的边距和填充,对 html 和 body 进行了全屏布局,并设置了相对定位。.back-to-top 类则定义了“回到顶部”按钮的样式,包括其位置、圆角、阴影、填充以及悬停时背景颜色的变化。此外,与 v-cloak 相关的 CSS 确保在 Vue 实例加载过程中隐藏该元素。每个 .page 类代表一个页面,每个页面的高度设置为 400px,用于模拟多页面的滚动效果。 接下来是 JavaScript 部分(backTop.js)。在这里,我们创建了一个 Vue 实例。实例的 el 属性指定 Vue 将挂载到的 DOM 元素(#back-to-top)。data 对象中包含三个属性:backTopShow 用于控制按钮的显示状态;backTopAllow 用于防止用户快速连续点击;backSeconds 定义了回到顶部所需的时间;showPx 则规定了滚动多少像素后显示“回到顶部”按钮。 在 V
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值