将变量或对象声明为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. linux之vi编辑器的基础命令

    1,假如要在这个php文件的phpinfo.php;之后加入一行,我们可以先按键盘的"a",光标就会跳转到之前绿色光标之后,也就是说,"a"是代表在当前光标之后 ...

  2. 使用Redis实现分布式锁

    在天猫.京东.苏宁等等电商网站上有很多秒杀活动,例如在某一个时刻抢购一个原价1999现在秒杀价只要999的手机时,会迎来一个用户请求的高峰期,可能会有几十万几百万的并发量,来抢这个手机,在高并发的情形 ...

  3. JAVA中线程的状态

    java thread的运行周期中, 有几种状态, 在 java.lang.Thread.State 中有详细定义和说明: NEW:至今尚未启动的线程的状态. RUNNABLE:可运行线程的线程状态. ...

  4. ar1220f-s四条拨号光纤做的策略路由实现负载均衡

    acl number 3001  //内网数据流不需被重定向到外网出口. rule 5 permit ip source 192.168.0.0 0.0.255.255  destination 19 ...

  5. 20155212 实验四 《Android程序设计》 实验报告

    20155212 实验四 <Android程序设计> 实验报告 (一)Android Stuidio的安装测试 参考<Java和Android开发学习指南(第二版)(EPUBIT,J ...

  6. PHP如何与搜索引擎Elasticsearch交互?

    一:参考官方文档 1. Elasticsearch 5.4.0英文手册:https://www.elastic.co/guide/en/elasticsearch/reference/5.4/sear ...

  7. Codeforces Round #392 (Div. 2)

    D题,给出n,k,k是n进制数,但是大于十进制时,它的表示方法仍为十进制那种,比如16进制下的15,我们可以看成就是15,或者1|5,也就是1×16+5 = 21,让你求出能表达的最小十进制数 从后面 ...

  8. CentOS下SparkR安装部署:hadoop2.7.3+spark2.0.0+scale2.11.8+hive2.1.0

    注:之前本人写了一篇SparkR的安装部署文章:SparkR安装部署及数据分析实例,当时SparkR项目还没正式入主Spark,需要自己下载SparkR安装包,但现在spark已经支持R接口,so更新 ...

  9. JavaSE教程-02Java基本语法-练习

    请说出下面的运算结果及解释为什么 System.out.println(1+1+"1");//? System.out.println("1"+1+1);//? ...

  10. nodejs - 守护进程 supervisor

    1. 安装   npm -g install supervisor   2. 如果使用了expres框架   需要修改启动方式 到 package.json中的   "scripts&quo ...