volatile是一个类型修饰符(type specifier)。它是被设计用来修饰被不同线程访问和修改的变量。如果没有volatile,基本上会导致这样的结果:要么无法编写多线程程序,要么编译器失去大量优化的机会。
可能你不太清楚volatile到底为什么要有这种修饰符,优化不是很好嘛?为什么他又会影响到多线程编程呢?
因为对于一个变量,某种情况下编译器就可以断定它可以把变量缓存到寄存器中,以后可以访问该寄存器来代替访问较慢的主板上的内存。这对于单线程代码来说是一个很好的优化,但是在现在这种情况下,它破坏了程序的正确性:当你调用了某个Gadget的Wait函数后,即使另一个线程调用了Wakeup,Wait还是会一直循环下去。这是因为flag_的改变没有反映到缓存它的寄存器中去。编译器的优化未免有点太……乐观了。
在大多数情况下,把变量缓存在寄存器中是一个非常有价值的优化方法,如果不用的话很可惜。C和C++给你提供了显式禁用这种缓存优化的机会。如果你声明变量是使用了volatile修饰符,编译器就不会把这个变量缓存在寄存器里——每次访问都将去存取变量在内存中的实际位置。这样你要对Gadget的Wait/Wakeup做的修改就是给flag_加上正确的修饰:
其实就是说如果变量本来是用来多线程同步访问的,则他要实时的处于正确数据变化中,而如果不用volatile,可能会因为被优化到缓存中,从而导致变量不能实时反映同步访问的状态,则会对多线程编程造成破坏。而如果声明为volatile的话,则显示告诉编译器,不要对我进行优化,这样,程序在读变量值的时候就会每次都到共享内存中读取内存中的实际数值了。