将变量或对象声明为volatile类型后,每次对变量的访问都是从其内存直接读取。那什么时候对变量的访问不是从其内存读取的呢?一种常见的情况就是编译器开启了优化选项,这时候对变量的访问有可能就是从寄存器中读取。

volatile是C/C++中的关键字,所以它是在多线程概念之前出现的,但要解释volatile的作用的话,如果我们不是搞嵌入式硬件开发的,那么在一个多线程程序的示例里对volatile的功能进行解释是最常见的,这就有点尴尬了- -! 比如以下是一个线程执行的函数,如果编译器开启了优化选项的话那么对于g_flag的访问都是从CPU寄存器中读取的,另一个线程如果g_flag修改为false的话这里的线程也不会退出,因为这里是从CPU寄存器中读取的值,而不是从g_flag的内存上读取到的值!

  void ThreadFun()
  {
    while(g_flag == true);
    do();
  }

我想C/C++编译器默认应该是不开启这种恶心的优化选项的,否则所有的共享数据都应该声明为volatile了。当然如果你的代码是开源的,你不知道别人的编译器有没有开启这个优化,为了保证安全性那么全局数据应该被声明为volatile。

最后总结一下,volatile是用来设置变量或对象值的读取方式为从内存读取,它与线程同步是两码事,主要用在下面的情况上:
     1、变量可能会被本程序之外的东西修改,如其它程序,操作系统、硬件操作。
     2、变量可能会被另一个线程修改,而且编译器开启了优化选项。

参考:《win32多线程程序设计》、《windows核心编程》、知乎:多线程编程中什么情况下需要加 volatile? 、知乎:C++多线程有必要加volatile么?

C/C++中的volatile究竟是什么鬼?的更多相关文章

  1. JavaScript深入浅出第1课:箭头函数中的this究竟是什么鬼?

    <JavaScript 深入浅出>系列: JavaScript 深入浅出第 1 课:箭头函数中的 this 究竟是什么鬼? JavaScript 深入浅出第 2 课:函数是一等公民是什么意 ...

  2. [读书笔记]java中的volatile关键词

    以下内容大多来自周志明的<深入理解Java虚拟机>. 当一个变量被volatile修饰后,它将具备两种特性: 1. 保证此变量对所有线程的可见性,这里的“可见性”是指当一条线程修改了这个变 ...

  3. zz剖析为什么在多核多线程程序中要慎用volatile关键字?

    [摘要]编译器保证volatile自己的读写有序,但由于optimization和多线程可以和非volatile读写interleave,也就是不原子,也就是没有用.C++11 supposed会支持 ...

  4. C语言中关键字volatile的含义【转】

    本文转载自:http://m.jb51.net/article/37489.htm 本篇文章是对C语言中关键字volatile的含义进行了详细的分析介绍,需要的朋友参考下 volatile 的意思是“ ...

  5. java多线程中的volatile和synchronized

    package com.chzhao; public class Volatiletest extends Thread { private static int count = 0; public ...

  6. OpenGL中glRotatef()函数究竟对矩阵做了什么

    OpenGL中glRotatef()函数究竟对矩阵做了什么 我们知道OpenGL中维持着两套矩阵,一个是模型视图矩阵(model view matrix),另一个是投影矩阵(projection ma ...

  7. java中的volatile关键字

    java中的volatile关键字 一个变量被声明为volatile类型,表示这个变量可能随时被其他线程改变,所以不能把它cache到线程内存(如寄存器)中. 一般情况下volatile不能代替syn ...

  8. java中的Volatile 变量

    Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”:与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少, ...

  9. C/C++中的volatile简单描述

    首先引入一篇博客: 1. 为什么用volatile? C/C++ 中的 volatile 关键字和 const 对应,用来修饰变量,通常用于建立语言级别的 memory barrier.这是 BS 在 ...

随机推荐

  1. JSP页面的静态包含和动态包含

    JSP中有两种包含:静态包含:<%@include file="被包含页面"%>和动态包含:<jsp:include page="被包含页面" ...

  2. 如何用PHP遍历文件数目 或删除目录下的全部文件?

    先说一下基础知识: 文件位置如下图所示: 1.判断是文件还是目录 var_dump(filetype("./aa/bb/cc.txt")); 输出: string(4) " ...

  3. c++堆与栈的简单认识

    堆: 操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删 除,并将该结点的空间分配给程序,另外,对于大多数 ...

  4. sublime工具篇

    sublime快捷键的应用 熟悉掌握sublime快捷键,提高编码效率,享受编码乐趣. window操作系统常用快捷键 win+D:快速显示桌面     win+方向键:最大化最小化窗口  win+L ...

  5. Targeted Learning R Packages for Causal Inference and Machine Learning(转)

    Targeted learning methods build machine-learning-based estimators of parameters defined as features ...

  6. javascript基础-闭包

    原理 函数里包含函数,即闭包. 包含函数的结果是,子函数会挟持父函数的活动对象.子函数在访问一个变量时,先读自身的活动对象,是否包含此变量,没有从父函数里找,还没有,去祖函数,层层回溯,直到windo ...

  7. 【Android】又一个Gank客户端来啦

    介绍 Gank平台的移动端又来了,非常感谢Gank平台开放接口,让我们这些小白有机会练手.学习. 本项目在架构方面有稍微花点心思,虽然还是最简单的MVC模式,但基本参考MVP的思想,Activity只 ...

  8. CI Weekly #20 | 从持续集成的角度看 “云” 的价值

    很多移动开发工程师对 fastlane 耳熟能详,最近 flow.ci 的 iOS 工作流「编译」这步已采用 fastlane gym 工具(iOS 应用打包签名自动化),进一步优化了构建打包速度.快 ...

  9. 【 js 基础 】【 源码学习 】源码设计 (持续更新)

    学习源码,除了学习对一些方法的更加聪明的代码实现,同时也要学习源码的设计,把握整体的架构.(推荐对源码有一定熟悉了之后,再看这篇文章) 目录结构:第一部分:zepto 设计分析第二部分:undersc ...

  10. JavaSE教程-01初识Java-思维导图

    图片看不清楚时: 1)可以将图片另存为图片,保存在本地来查看 2)右击在新标签中打开放大查看. 分解: 1.计算机基本概念的普及 硬件 cpu.内存.硬盘等 软件 系统级软件 Windows.Linu ...