class Gadget 
  { 
  public: 
  void Wait() 
  { 
  while (!flag_) 
  { 
  Sleep(1000); // sleeps for 1000 milliseconds 
  } 
  } 
  void Wakeup() 
  { 
  flag_ = true; 
  } 
  ... 
  private: 
  bool flag_; 
  }; 
 
这个程序就是百度上复制来的 说是错误的 要把“bool flag_;”改为“volatile bool flag_;”好像如果是多线程 才会出现这样的问题 但是这个代码也反应不出来多线程啊 是不是用Wakeup去改flag_的时候 while循环也在执行 这样就是多线程了吗 我接触线程还比较少 所以请大家指点迷津 帮我详细说说

解决方案 »

  1.   

    多个线程执行上面的同一段代码,访问同一个全局变量等...用volatile来修饰这个全局变量,防止编译器对它优化,从而影响同步
      

  2.   

    lS的 谢谢你的回答
    如果这样的情况呢 
    就是比如程序开始就开始反复处理一个数字 比如不停的++ , 然后弄个计时器 固定时候发消息 而处理消息的程序就是显示这个数字现在的值 那么这个数字变量 在定义的时候需要加上这个volatile这个变量吗?
    处理消息的线程 和 对这个数字变量不停++的线程是一个线程吗?谢谢指教啊 
      

  3.   

    谢谢LS的解答
    请问LS的大侠  当一个函数处理一个数据的时候 如果没有处理完 也没有返回 那么在让出处理器的时候 数字没有保存在内存中吗 而是保存在某个寄存器中 那么正巧有另外一个函数取得处理器 开始读取这个数 读的是内存中的 而不是寄存器中的 然后就不能保持同步了 是这样吗那么万一这不是一个数字 而是一群数字 有那么多寄存器去保存吗?
      

  4.   

    volatile 是个类型修正符(type modifier)
    volatile 保证编译器不对该对象进行优化,每次需要它的值时都重新读取。
    意思就是说当没有volatile标识的对象,在编译器编译时,如果编译器觉得可以用一个常量来
    代替这个对象的值的话,编译器会把没有volatile标识的对象转换成一个常量来进行优化!泛型<编程>:volatile——多线程程序员最好的朋友volatile 修正符及让你的编译器为你检查
    竞态条件(race conditions)
      

  5.   

    谢谢LS的解答 那么我该在什么是时候去用这个volatile 换句话说 什么时候如果不用这个修饰符 会使得程序有可能出现错误呢
      

  6.   

    对于多线程引用全局变量来说,建议使用volatile修饰,它的作用是告诉编译器无需对该变量作任何优化,即无需将它放到一个寄存器中,并且该值可被外部改变。
      

  7.   

    你的代码明显Wait是一个线程,WakeUp在另一个线程运行.如果不声明成volatile,即使在WakeUp中更改了内存中的flag,由于编译器优化,在Wait中直接用寄存器中保存的flag而不是重新从内存中读取,所以这个修改无法被Wait探测到,从而导致Wait中的循环永远无法退出.