C/C++中的volatile究竟是什么鬼?

volatile是C/C++中的一个关键字,将变量或对象声明为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么?

时间: 2024-10-25 14:10:18

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

扒一扒最近爆火的SDT-LUCK CLUB究竟是什么鬼?

Super Single Dog(超级单身狗)游戏从昨晚上线到现在十分火爆,大批量的玩家进场!今天我们来扒一扒这款区块链去中心化的游戏究竟是什么鬼? Super Single Dog(超级单身狗)是全球知名游戏开发公司LUCK CLUB(幸运俱乐部)旗下首款区块链去中心化游戏.SDT是区块链发展以来最具综合应用的应用产品. 大家都知道,区块链发展以来,经历了可编程货币.可编程金融与可编程智能社会的三个阶段,准确地说就是在应用上引用了挖矿(工作量证明机制).智能合约系统及数据防伪等技术.那么,SD

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

本文转载自:http://m.jb51.net/article/37489.htm 本篇文章是对C语言中关键字volatile的含义进行了详细的分析介绍,需要的朋友参考下 volatile 的意思是“易失的,易改变的”.这个限定词的含义是向编译器指明变量的内容可能会由于其他程序的修改而变化.通常在程序中申明了一个变量时,编译器会尽量把它存放在通用寄存器中,例如ebx.当CPU把其值放到ebx中后就不会再关心对应内存中的值.若此时其他程序(例如内核程序或一个中断)修改了内存中它的值,ebx中的值并

理解java中的volatile关键字

Java语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了 实现代码线程的安全性.Java 语言中的 volatile 变量可以被看作是一种 "程度较轻的 synchronized":与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分. volatile 写和读的内存语义: 线程 A 写一个 volatile 变量,实质上是线程 A

java中的Volatile 变量

Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”:与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是 synchronized 的一部分.本文介绍了几种有效使用 volatile 变量的模式,并强调了几种不适合使用 volatile 变量的情形. 锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility).互斥即一次 只允许一个线程持

java中的 Volatile

Java 语言包含两种内在的同步机制:同步块(或方法)和 volatile 变量.这两种机制的提出都是为了实现代码线程的安全性.其中 Volatile 变量的同步性较差(但有时它更简单并且开销更低),而且其使用也更容易出错. Java 语言中的 volatile 变量可以被看作是一种 “程度较轻的 synchronized”:与 synchronized 块相比,volatile 变量所需的编码较少,并且运行时开销也较少,但是它所能实现的功能也仅是synchronized 的一部分.本文介绍了几

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

以下内容大多来自周志明的<深入理解Java虚拟机>. 当一个变量被volatile修饰后,它将具备两种特性: 1. 保证此变量对所有线程的可见性,这里的“可见性”是指当一条线程修改了这个变量的值,新值对于其他线程来说是可以立即得知的.而普通变量不能做到这一点,普通变量的值在线程间传递均需要通过主内容来完成,例如,线程A修改了一个普通变量的值,然后向主内容进行回写,另外一条线程B在线程A回写完成之后再从主内存进行读取操作,新变量值才会对线程B可见. volatile变量在各个线程的工作内存中不存

C++中的volatile(Primer读书笔记)

时间:2014.05.24 地点:基地 -------------------------------------------------------------------------- 一.简述 volatile限定符平时很少用到,今天倒是碰到了,所幸探个明白.volatile 英文字面意思是"不稳定的",确切的计算机含义时与机器相关,所以在对包含volatile的程序在移植到新机器或使用不同的编译器时往往还需要对编译器进行一些改变. -----------------------

C中的volatile关键字

volatile提醒编译器它后面所定义的变量随时都有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据.如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象.下面举例说明.在DSP开发中,经常需要等待某个事件的触发,所以经常会写出这样的程序:short flag;void test(){do1();while(flag==0);do2();} 这段程序等待内存变量flag的

java多线程中的volatile和synchronized

package com.chzhao; public class Volatiletest extends Thread { private static int count = 0; public void run() { count++; } public static void main(String[] args) { Thread threads[] = new Thread[10000]; for (int i = 0; i < threads.length; i++) { thre