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

  • 2016年07月31日 18:28
  • 15.32MB
  • 下载

volatile变量详解

  • 2013年12月31日 17:45
  • 202KB
  • 下载

i++ 是否为原子操作 和 Java中的volatile关键字

研究ThreadPoolExecutor的时候,发现其中大量使用了volatile变量。  不知为何,因此做了一番查找,研究:  其中借鉴了很多网上资料。  在了解volatile变量作...

C中Volatile用法.doc

  • 2013年05月30日 10:38
  • 24KB
  • 下载

volatile_unsigned_int

  • 2013年03月22日 23:27
  • 197KB
  • 下载

volatile 和 atomic 原子性的区别和联系

作者:wenyinfeng 转载时,请注明原文出处: http://blog.sina.com.cn/s/blog_c00b6f6201016mbk.html 谢谢! An incorrec...

volatile用法

  • 2009年03月19日 01:05
  • 37KB
  • 下载

c语言之volatile和register关键字

//register.cpp #include #include #include int main1() { for(register int i=0;i
  • earbao
  • earbao
  • 2016年12月28日 00:10
  • 920

volatile变量

  • 2009年06月05日 15:17
  • 85KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:volatile
举报原因:
原因补充:

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