1、使用volatile的背景

直接处理硬件的程序常常包含这样的数据元素,它们的值由程序直接控制之外的过程控制。举例如下 :

i、程序可能包含一个由系统时钟定时更新的变量。当对象的值可能在程序的控制或检测之外被心迹时,应该将该对象声明为volatile。告诉编译器不应对这样的变量进行优化。

ii、变量读取

volatile int i = 10;
int k = i;
这段代码如果没有加上volatile,它的执行过程是 i = 10, 10 ->reg寄存器,k = reg值,就是说,k=i实际上是从寄存器里读出来的。这样快捷高效,当然并不是每次都这样,因为寄存器有限。如果在10->reg寄存器的时候,i存储的内存变化了,也就是别的线程修改了i的值,k=i仍然会按照i=10来执行
加上volatile后,执行过程是 i = 10, k = *(int *)(&i); 它会从i的内存地址上去读,当然值会非常准确,但是效率会比从寄存器中读要慢很多。

iii、来自jave虚拟机中的参考

什么是主内存?为什么是在主内存中?先看看java的内存模型(JMM)中内存与线程的关系。

图片来自《深入理解Java虚拟机》

JMM中的内存分为主内存和工作内存,其中主内存是所有线程共享的,而工作内存是每个线程独立分配的,各个线程的工作内存之间相互独立、互不可见。在线程启动的时候,虚拟机为每个内存分配了一块工作内存,不仅包含了线程内部定义的局部变量,也包含了线程所需要的共享变量的副本,当然这是为了提高执行效率,读副本的比直接读主内存更快。

那么对于volatile修饰的变量(共享变量)来说,在工作内存发生了变化后,必须要马上写到主内存中,而线程读取到是volatile修饰的变量时,必须去主内存中去获取最新的值,而不是读工作内存中主内存的副本,这就有效的保证了线程之间变量的可见性。

2、C++的简单举例运用(只是用,没讲实质)

i、用法类比const修饰符,可以声明volatile指针、指向volatile对象的指针以及指向volatile对象的volatile指针:

volatile int v;//v是一个volatile int
int* volatile vip;//vip是一个volatile指针,它指向int
volatile int* ivp;//ivp是一个指针,它指向一个volatile int
volatile int* volatile vivp;//vivp是一个volatile指针,它指向一个volatile intint *ip = &v;//错误:必须使用指向volatile的指针
ivp = &v;//正确:ivp是一个指向volatile的指针
vivp = &v;//正确:vivp是一个指向volatile的volatile指针

ii、合成的拷贝对volatile对象无效

const和volatile的一个重要区别是我们不能使用合成的考贝/移动构造函数及赋值运算符初始化volatile对象或从volatile对象赋值。解释:因为合成的成员接受的形参类型是(非volatile)常量引用,显然不能把一个非volatile引用绑定到一个volatile对象上。

如需拷贝、移动或赋值它的volatile对象,则该类必须自定义拷贝或移动操作。代码举例如下:

class Foo {
pubilc:Foo(const volatile Foo&);//从一个volatile对进行拷贝Foo& operator=(volatile const Foo&);//将一个volatile对象赋值给一个非volatile对象Foo& operator=(volatile const Foo&) volatile;//将一个volatile对象赋值给一个volatile对象//Foo类的剩余部分
};

参考博文:

https://blog.csdn.net/u011519624/article/details/63686701

volatile限定符——C++讲解相关推荐

  1. C++ 学习笔记(19)new/delete表达式、定位new、typeid、dynamic_cast、type_info、枚举类型、成员函数指针、union、位域、volatile限定符、链接指示

    C++ 学习笔记(19)new/delete表达式.定位new.typeid.dynamic_cast.type_info.枚举类型.成员函数指针.union.位域.volatile限定符.链接指示 ...

  2. volatile限定符

    备注:volatile的确切含义与机器有关,只能通过阅读编译器文档来理解.要想让使用了volatile的程序在移植到新机器或新编译器后仍然有效,通常需要对该程序进行某些改变. 直接处理硬件的程序常常包 ...

  3. 固有的不可移植的特征之volatile限定符

    volatile的确切含义与机器相关,只能通过阅读编译器文档来理解,使用volatile的程序在移到新的机器或编译器时通常必须改变. 直接处理硬件的程序常具有这样的数据成员,它们的值由程序本身直接控制 ...

  4. volatile限定符{C}

    PS: ...Newbie love coding-  Linux_c一站式编程(volatile限定符介绍) linux_c的volatile限定符 现在探讨一下编译器优化会对生成的指令产生什么影响 ...

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

      在C语言经常会用到变量类型限定符const和volatile,但是const和 volatile也可以一起使用.下面就一次分析一下这三种情况的使用方法. 1.const   从字面意思理解,意思就 ...

  6. 细谈volatile限定符——上海先锋商泰面试归来

    volatile的本意是"易变的",由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化.比如: static int i=0; int main(voi ...

  7. C语言volatile类型限定符详解

    一.volatile类型限定符 volatile是一个类型修饰符(type specifier),就像我们熟悉的const一样,它是被设计用来修饰被不同线程访问和修改的变量:volatile的作用是作 ...

  8. c语言restrict和const,C语言中const、volatile、restrict等类型限定符的区别

    auto.register.static.extern是属于存储类修饰符.在声明时,存储类修饰符最多只能使用一个,而且无法用在typeof声明中. 而类型限定符是指const.volatile.res ...

  9. C语言中的类型限定符有哪些?

    C语言中有一些关键字起到了限定的作用,他们被称为限定符,那么在C语言中共有几个限定符呢?他们的作用分别是什么呢?本文主要介绍C中4个限定符 1.const2.volatile3.restrict4._ ...

最新文章

  1. c 宏定义用法#define
  2. AWS 中国宁夏和北京区正式上线 Amazon SageMaker,中国用户终于能用到新工具和功能!
  3. Mask_RCNN训练自己的模型(练习)
  4. Android BLE(3) ---FastBle解析
  5. Hls之Hls.js源码解析
  6. kindeditor上传图片php,使用 KindEditor 编辑器PHP语言本地上传图片提示错误
  7. 理解一下 GK Zone 20 与GK Zone 20N的区别
  8. 华为鸿蒙如何添加桌面小组件,万能小组件添加至桌面怎么弄?桌面添加应用方法图文详解...
  9. Android ViewModel与LiveData组件组合使用详解
  10. python xpath定位 麦客表单
  11. Java集合中Set
  12. HANA S/4 标准表(MARC MBEW COBL)增强流程
  13. 论文笔记--GMAN: A Graph Multi-Attention Network for Traffic Prediction
  14. SurfaceGo_BMR_41_1.011.2.zip恢复镜像网盘满速下载地址
  15. 最小点权覆盖集最大点权独立集
  16. 暴雪在洛杉矶建了自己的电竞馆,守望先锋锦标赛下个月就会在这里举行
  17. visual studio如何设置背景图片
  18. 奥迪 a4 编码 控制计算机,大众/奥迪车电脑编码大全).doc
  19. 全国分县行政区划图(zz)
  20. 集成了补丁的windows xp 操作系统

热门文章

  1. vivos9更改控制中心样式(修改方法分享)
  2. Arduino DIY 电子自动浇花浇水系统
  3. 4天狂销20万盒,GMV超5620万,应季爆品有哪些营销关键词?
  4. HTML.网页程序设计
  5. put请求400状态码
  6. 全新UI流量卡官网系统源码+有后台带文章
  7. 台式计算机内存是什么问题,如何解决台式机上内存不足的问题
  8. 将BMP图片转换成ICON图标
  9. 创建Mesh-格子地图转NavMesh-可破坏墙壁
  10. 读书笔记 | 4.2 通用信用评分:应用与发展