volatile变量直接在CPU和内存之间交换,不通过一级、二级缓存。
考虑下面的代码:
代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Gadget
{
public:
    void Wait()
    {
        while (!flag_)
        {
            Sleep(1000); // sleeps for 1000 milliseconds
        }
    }
void Wakeup()
{
    flag_ = true;
}
//...
private:
    bool flag_;
};

上面代码中Gadget::Wait的目的是每过一秒钟去检查一下flag_成员变量,当flag_被另一个线程设为true时,该函数才会返回。至少这是程序作者的意图,然而,这个Wait函数是错误的。
      假设编译器发现Sleep(1000)是调用一个外部的库函数,它不会改变成员变量flag_,那么编译器就可以断定它可以把flag_缓存在寄存器中,以后可以访问该寄存器来代替访问较慢的主板上的内存。这对于单线程代码来说是一个很好的优化,但是在现在这种情况下,它破坏了程序的正确性:当你调用了某个Gadget的Wait函数后,即使另一个线程调用了Wakeup,Wait还是会一直循环下去。这是因为flag_的改变没有反映到缓存它的寄存器中去。编译器的优化未免有点太……乐观了。
      在大多数情况下,把变量缓存在寄存器中是一个非常有价值的优化方法,如果不用的话很可惜。C和C++给你提供了显式禁用这种缓存优化的机会。如果你声明变量是使用了volatile修饰符,编译器就不会把这个变量缓存在寄存器里——每次访问都将去存取变量在内存中的实际位置。这样你要对Gadget的Wait/Wakeup做的修改就是给flag_加上正确的修饰:

1
2
3
4
5
6
7
class Gadget
{
public:
    //... as above ...
private:
    volatile bool flag_;
};

转载于:https://www.cnblogs.com/duyy/p/3666442.html

volatile关键字的使用相关推荐

  1. java中实现具有传递性吗_Java中volatile关键字详解,jvm内存模型,原子性、可见性、有序性...

    一.Java内存模型 想要理解volatile为什么能确保可见性,就要先理解Java中的内存模型是什么样的. Java内存模型规定了所有的变量都存储在主内存中.每条线程中还有自己的工作内存,线程的工作 ...

  2. volatile关键字之全面深度剖析

    引言 volatile这个关键字可能很多朋友都听说过,或许也都用过.在Java 5之前,它是一个备受争议的关键字,因为在程序中使用它往往会导致出人意料的结果.在Java 5之后,volatile关键字 ...

  3. c语言中volatile关键字的作用

    读文章之前 可以先看一下<程序员的自我修养 >第28页 过度优化. volatile 提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直 ...

  4. C语言volatile关键字详解

    volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据.如果没有volatile关键字,则编译器可能优化读取和存储 ...

  5. 爆赞,对 volatile 关键字讲解最好的一篇文章!

    欢迎关注方志朋的博客,回复"666"获面试宝典 最近,在一篇文章中了解到了 volatile 关键字,在强烈的求知欲趋使下,我查阅了一些相关资料进行了学习,并将学习笔记记录如下,希 ...

  6. Java并发编程:JMM和volatile关键字

    Java内存模型 随着计算机的CPU的飞速发展,CPU的运算能力已经远远超出了从主内存(运行内存)中读取的数据的能力,为了解决这个问题,CPU厂商设计出了CPU内置高速缓存区.高速缓存区的加入使得CP ...

  7. c#中volatile关键字的作用

    恐怕比较一下volatile和synchronized的不同是最容易解释清楚的.volatile是变量修饰符,而synchronized则作用于一段代码或方法:看如下三句get代码: int i1;  ...

  8. 26张图带你彻底搞懂volatile关键字

    引子 小艾吃饭路上碰上小牛,忙问:你昨天面大厂面的咋样了?听说他们最喜欢问多线程相关知识. 小牛说:对啊,第一个问题我就讲了20分钟,直接把面试官讲服了. 小艾忙问:什么问题能讲这么久?是不是问你情感 ...

  9. C++中的volatile关键字

    1.使用 volatile int i = 10; 2.使用volatile时要几个注意的点: volatile 关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素(操作系统.硬 ...

  10. volatile关键字的作用、原理

    在只有双重检查锁,没有volatile的懒加载单例模式中,由于指令重排序的问题,我确实不会拿到两个不同的单例了,但我会拿到"半个"单例. 而发挥神奇作用的volatile,可以当之 ...

最新文章

  1. ThinkingInJava_3
  2. linux命令less
  3. adc0832对光电二极管进行数据采集_实验十adc0832数模转换的显示
  4. JVM 的 Finalization Delay 引起的 OOM(java.lang.OutOfMemoryError:null at sun.misc.Unsafe.allocateMemory.)
  5. Oracle 创建用户 scott 例
  6. quickServer介绍
  7. python读取txt文件中的数字_在python中从文本文件读取两列数字
  8. 2015上海网络赛 HDU 5475 An easy problem 线段树
  9. Android开发笔记——快速入门(从入门ACT到Fragment放肆)
  10. 蝶形算法(H.264)
  11. Java 冒泡排序的使用
  12. 微信小程序实现扫码登录网站
  13. 常用单片机模块(四)
  14. NFT和游戏化的革命-通过 Play Earn 尝试世界上第一个国际象棋游戏
  15. 计算机维修情况说明书,电脑坏了(电脑坏了情况说明)
  16. 基于SpringBoot vue的电脑商城平台源码和论文含支付宝沙箱支付
  17. saltstack自动化运维一键部署rpm安装httpd和源码安装nginx
  18. C语言 有3个数a,b,c,要求按大小顺序把他们输出
  19. Halcon+C#显示一张图片
  20. PHP实现微信公众平台开发---提升篇(网页授权接口)

热门文章

  1. PS3支持的显示标准介绍
  2. oracle函数 sysdate
  3. DSO windowed optimization 代码 (3)
  4. 3.3、自定义错误页面
  5. kendo-ui学习笔记——题记
  6. 某final神犇的工作感想
  7. TreeTemplate树模板
  8. C# 的Delegate(委托)
  9. Re: 社团改革还让不让人活了?
  10. matlab中腐蚀图像的编写,Matlab实现二值图像的腐蚀算法源代码