volatile

转载 2015年07月09日 15:31:19

只是个小小的关键字
 尽管C和C++标准都明显地对线程保持沉默,它们还是对多线程做了小小的让步,这种让步表现为volatile关键字。
 正如它的更为人所知的伙伴const, volatile是个类型修正符(type modifier)。。它的作用是和变量连用使变量能被不同线程访问和修改。根本上说,如果没有volatile的话,要么不可能写出多线程程序,要么编译器浪费极大的优化机会。现在来解释为什么会是这种情况。
 考虑下面代码:

class Gadget
{
public:
 void Wait ()
 {
  while (!flag_)
  {
   Sleep(1000); //睡眠1000毫秒
  }
 }
 void Wakeup ()
 {
  flag_ = true;
 }
 ...
private:
 bool flag_;
};

上面Gadget::Wait的作用是每秒检查一次flag_成员变量,如果那个变量被其他线程设为true时返回。至少这是程序员的本来意图,但,唉,Wait函数是错误的。
 如果编译器断定Sleep(1000)是对外部库的一个调用,而且这个调用不可能修改成员变量flag_。那么编译器会决定在寄存器中缓存flag_并且用那个寄存器替代较慢的内存。这对单线程代码来说是非常好的优化,但在现在这个情况下,这个优化破坏了正确性:你对某个Gadget对象调用Wait后,尽管另一个线程调用了Wakeup,Wait还会永远循环下去。这是因为对flag_的修改不会反映到缓存flag_的寄存器。这个优化实在是......过度优化了。
 把变量缓存到寄存器中在大多数时候是一项非常有用的优化,浪费掉就太可惜了。C和C++给你机会来显式禁用这个优化。如果你用volatile标识一个变量,编译器就不会把那个变量缓存到积存器中——对变量的每次访问都直接通过实际内存的位置。所以要让Gadget的Wait/Wakeup正常工作只要正确修饰flag_

class Gadget
{
public:
 ...同上...
private:
 volatile bool flag_;
};

大多数对volatile用途和用法的解释到此为止,并且建议你在多线程中对基本类型加volatile标识符。但是,用volatile你可以做更多事情,因为它是C++奇妙的类型系统的一部分。

关于volatile关键字的用法,从汇编透视C语法操作

看一个简单的c程序,p是没加关键字volatile的int型指针,r是加关键字volatile的int型指针。 //main.c #include void main(void) { ...
  • ZHONGkunjia
  • ZHONGkunjia
  • 2016年04月18日 22:06
  • 641

java之用volatile和不用volatile的区别

在当前的Java内存模型下,线程可以把变量保存在本地内存(比如机器的寄存器)中,而不是直接在主存中进行读写。这就可能造成一个线程在主存中修改了一个变量的值,而另外一个线程还继续使用它在寄存器中的变量值...
  • feier7501
  • feier7501
  • 2014年02月26日 21:41
  • 51376

C/C++中volatile的用法

volatile是“易变的”、“不稳定”的意思。volatile是C/C++的一个较为少用的关键字,它用来解决变量在“共享”环境下容易出现的读取错误的问题。...
  • K346K346
  • K346K346
  • 2015年07月18日 11:56
  • 3686

volatile和__volatile__是什么意思?

 volatile和__volatile__是什么意思? a. volatile是C语言定义的关键字,gcc为了需要又定义了__volatile__,它和 volatile表达的是同一意思。 b. v...
  • jemmy
  • jemmy
  • 2006年02月21日 23:14
  • 1258

裸机驱动之理解(*(volatile unsigned *)

#define rGPIOFDAT (*(volatile u32 *)0x7f0080a4)  理解如上宏定义,需要从两个部分: 第一:强转指针类型 (volatile u32 *)0x7...
  • tankai19880619
  • tankai19880619
  • 2013年05月02日 22:14
  • 1189

C/C++(&Java) Volatile关键词深度剖析

背景 前几天,发了一条如下的微博 (关于C/C++ Volatile关键词的使用建议):   此微博,引发了朋友们的大量讨论:赞同者有之;批评者有之;当然,更多的朋友,是希望我能更详细...
  • gadbee5
  • gadbee5
  • 2016年05月30日 17:15
  • 1023

*(volatile int *)的理解

最近在SDK中遇到这么一句话*(volatile int *)(XPAR_GPIO_1_BASEADDR) 指向该地址的内容对LED的8bit GPIO口进行操作#define LED_Reg *(v...
  • u012123989
  • u012123989
  • 2016年07月15日 15:08
  • 927

使用volatile的例子

package com.my; class MultiThreadingExample implements Runnable { private volatile int testVal...
  • swingseagull
  • swingseagull
  • 2012年04月02日 13:18
  • 1860

对volatile修饰符的理解和使用

1. 什么是volatile修饰符? volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其他线程等。遇到这个关键字声明的变量,编译...
  • nevasun
  • nevasun
  • 2012年03月23日 17:14
  • 5076

volatile类型的数据

就像大家更熟悉的const一样,volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。volatile的作用是: 作为指令关键字,确保本条指令...
  • andrewgithub
  • andrewgithub
  • 2017年02月27日 16:11
  • 287
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:volatile
举报原因:
原因补充:

(最多只允许输入30个字)