0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

一般什么时候需要使用volatile关键字

电子设计 来源:电子设计 作者:电子设计 2020-12-24 17:29 次阅读

想必大家平时都见过volatile关键字,可是大家知道什么时候需要使用volatile关键字吗?

直接看下面代码:

int a = 100;

while (a == 100) { // code}

这段程序编译时,如果编译器发现程序始终没有企图改变a的值,那它可能就会优化这段代码,变成while(true)的死循环使得程序执行的更快,然而这种优化有时候会变成过度优化,编译器有时候可能没有意识到程序会改变a的值,却做了这种优化导致程序没有产生预期的行为。

这里为了产生预期的行为,需要阻止编译器做这种优化,可以使用volatile关键字修饰。

volatile int a = 100;

volatile关键字和const关键字相对应,const关键字告诉编译器其修饰的变量是只读的,编译器根据只读属性做一些操作,而volatile关键字告诉编译器其修饰的变量是易变的,同理编译器根据易变属性也会做一些操作。它会确保修饰的变量每次都读操作都从内存里读取,每次写操作都将值写到内存里。volatile关键字就是给编译器做个提示,告诉编译器不要对修饰的变量做过度的优化,提示编译器该变量的值可能会以其它形式被改变。

volatile修饰结构体时,结构体的成员也是volatile的吗

struct A { int data;};volatile A a;const A b;

答案是结构体内所有的都是volatile,引用c++标准里的一句话:

[Note: volatile is a hint to the implementation to avoid aggressive optimization involving the object because the value of the object might be changed by means undetectable by an implementation. See 1.9 for detailed semantics. In general, the semantics of volatile are intended to be the same in C + + as they are in C. ]

这里大体可以理解为一个对象是volatile,那对象里所有的成员也都是volatile。其实const和volatile可以理解为是硬币的两面,我们经常听到看到传说中的CV修饰词就是const和volatile关键字。

volatile可以保证原子性吗?

想必大家都知道答案,volatile只保证内存可见性,不能保证操作是原子的,拿i++举例:

volatile int i = 0;i++; // i = i + 1

i++ 相当于i=i+1,而i=i+1其实可以分解为好几步:

先读取i的值到tmp

增加tmp的值

把tmp的值写回到i的地址里

而volatile只能保证内存可见,可以理解为上述三步中的每一步都是原子的,但是三步合起来却不一定是原子的,因为在多线程中三步中间可能插入一些其它操作改变了预期的行为,所以volatile不能用在多线程中,多线程中的原子操作还是需要使用atomic。单例模式的double check方法中instance变量为什么需要使用volatile修饰也是这个原理。

小总结

tips:volatile不能解决多线程安全问题,针对特种内存才需要使用volatile,它和atomic的特点如下:std::atomic用于多线程访问的数据,且不用互斥量,用于并发编程中。

volatile用于读写操作不可以被优化掉的内存,用于特种内存中。

审核编辑:符乾江
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 程序编译
    +关注

    关注

    0

    文章

    9

    浏览量

    5461
  • volatile
    +关注

    关注

    0

    文章

    45

    浏览量

    13028
收藏 人收藏

    评论

    相关推荐

    ADS1299重新烧录后就是堆杂波,造成这样的原因一般是什么?

    关于ADS1299的疑惑,我的程序烧入到自己做的板卡,有时候就能正常采样,无论是外部信号发生器的波形,还是内部测试方波,但有时候重新烧录后(程序一字未动)就是堆杂波。请问造成这样的
    发表于 12-19 08:48

    C语言关键字分别发生在哪个阶段

    在编译的第个阶段:预处理,对些宏定义做替换。 第二个,const。 C语言中的 const 用于修饰只读变量,表示变量本身不能修改。 这个关键字会在编译的第二步起作用,也就是编译。强行修改
    的头像 发表于 11-24 10:31 182次阅读

    C语言关键字--typedef

    C语言关键字使用方法学习指南!
    的头像 发表于 10-07 12:44 264次阅读

    退耦电容一般用多大

    退耦电容的容量选择并不是成不变的,而是需要根据具体的电路设计需求和工作条件来确定。以下是对退耦电容容量选择的一般原则和考虑因素:
    的头像 发表于 09-26 11:28 469次阅读

    一般运算放大器什么时候是数字电压供电什么时候是模拟电压供电?

    您好,我发现在有的电路中,运算放大器是数字电源,有时候又是模拟电源供电,请问一般运算放大器什么时候是数字电压供电什么时候是模拟电压供电?
    发表于 09-11 06:03

    一般继电器需要多少电流才能驱动

    一般继电器所需的驱动电流会根据其型号、规格和额定工作电压等因素有所不同。通常,继电器需要定的电流来驱动其线圈产生磁场,从而使触点闭合或断开。以下是对继电器驱动电流的一般性说明:
    的头像 发表于 09-05 15:18 2967次阅读

    使用边缘AI和Sitara处理器进行关键字检测

    电子发烧友网站提供《使用边缘AI和Sitara处理器进行关键字检测.pdf》资料免费下载
    发表于 09-02 11:30 0次下载
    使用边缘AI和Sitara处理器进行<b class='flag-5'>关键字</b>检测

    typedef struct和直接struct的区别

    使用方式和灵活性上存在些区别。下面详细解释这两种方式的区别和用法。 直接使用 struct 当你直接使用 struct 关键字定义个结构体时,你创建了个新的类型,但你
    的头像 发表于 08-20 10:58 2773次阅读

    什么时候需要用到no phase reversal运放呢?

    什么时候需要用到no phase reversal运放呢? 此时不用的话会造成什么影响呢?
    发表于 08-02 14:09

    快速掌握C语言关键字

    C语言中的32个关键字你知道多少个呢?根据关键字的作用分为四类:数据类型关键字、控制语句关键字、存储类型关键字和其它
    的头像 发表于 07-06 08:04 351次阅读
    快速掌握C语言<b class='flag-5'>关键字</b>

    工控机寿命一般几年

    工控机,作为工业控制的核心设备,其使用寿命受到多种因素的影响。一般来说,工控机的正常使用寿命通常在 5 年到 10 年之间 12。但这范围并非绝对,具体的使用寿命还会受到以下几个关键因素的影响:
    的头像 发表于 06-25 10:00 882次阅读

    内联函数定义 为什么需要内联函数

    inline关键字是C99标准的型关键字,其作用是将函数展开,把函数的代码复制到每个调用处。
    的头像 发表于 02-19 12:20 547次阅读

    关键字搜索文件夹中某个TXT文件

    文件夹中随时创造TXT文件,如何及时选出刚创造的文件?或关键字搜索出需要的TXT文件?
    发表于 02-06 15:22

    在NVM和本地\"内存中定义数组(静态 /global /local)的\"关键字是什么?

    在 NVM 和本地\"内存中定义数组(静态 /global /local)的\"关键字是什么? 还有与 32 位对齐的关键字怎么样。
    发表于 01-25 07:52

    请问电机绕组保护编号一般怎么选?

    什么时候选择PTC,什么时候选择PT100,加6个PT100主要是考虑什么呢? 有什么原则,大家一般怎么选择?
    发表于 01-10 06:11