首先声明一点,本文是关于volatile关键字的学习,学习内容主要是来自一些大牛的网络博客。
一篇是何登成先生的C/C++ Volatile关键词深度剖析(http://hedengcheng.com/?p=725)
一篇是chao_yu的C/C++中volatile关键字详解(https://www.cnblogs.com/yc\_sunniwell/archive/2010/07/14/1777432.html)
还有一篇来自于官方文档(https://zh.cppreference.com/w/cpp/language/cv)
本文旨在于学习和记录,因此会有一些内容直接抄的上述博客,向上述博客大牛致以崇高的敬意。特此声明。
在看代码的时候,发现有使用volatile的关键字,但是一知半解,因此搜索了一些关于volatile的相关资料。总结(摘抄)如下:
1. CV类型限定符中,const被定义为常类型,volatile 被定义为易变的类型。
_const 对象_——类型为 const-qualified 的对象,或 const 对象的非 mutable 子对象。这种对象不能修改:尝试直接这么做是编译时错误,且尝试间接这么做(例如通过到非 const 类型的引用或指针修改 const 对象)导致未定义行为。
volatile 对象——类型为 volatile-qualified 的对象,或 volatile 对象的子对象,或 const volatile 对象的 mutable 子对象。通过 volatile 限定类型泛左值表达式的每次访问(读或写操作、成员函数调用等)都被当作对于优化目的的可见副效应(即在执行的单一线程内, volatile 访问不能被优化掉或者与另一先序或后序于该 volatile 访问的可见副效应重排序。这使得 volatile 对象适用于与信号处理函数的交流,但不适于与另一执行线程交流,参阅 std::memory_order )。试图通过非 volatile 泛左值引用 volatile 对象(例如,通过到非 volatile 类型的引用或指针)会导致未定义行为。
_const volatile 对象_——类型为 const-volatile-qualified 的对象, const volatile 对象的非 mutable 子对象, volatile 对象的 const 子对象,或非 mutable 对象的 const 子对象。表现同 const 对象与 volatile 对象两者。
2.volatile的特性
2.1 易变性。 在汇编层面观察,两条语句,下一条语句不会直接使用上一条语句对应的volatile变量的寄存器内容,而是直接从内存中读取。
2.2 不可优化性。volatile告诉编译器,不要对我这个变量进行各种激进的优化,甚至将变量直接消除,保证程序员写在代码中的指令,一定会被执行。相对于前面提到的第一个特性:”易变”性,”不可优化”特性可能知晓的人会相对少一些。
2.3 顺序性。C/C++ Volatile关键词前面提到的两个特性,让Volatile经常被解读为一个为多线程而生的关键词:一个全局变量,会被多线程同时访问/修改,那么线程内部,就不能假设此变量的不变性,并且基于此假设,来做一些程序设计。当然,这样的假设,本身并没有什么问题,多线程编程,并发访问/修改的全局变量,通常都会建议加上Volatile关键词修饰,来防止C/C++编译器进行不必要的优化。
3.总结
C/C++ Volatile关键词的第三个特性:”顺序性”,能够保证Volatile变量间的顺序性,编译器不会进行乱序优化。Volatile变量与非Volatile变量的顺序,编译器不保证顺序,可能会进行乱序优化。同时,C/C++ Volatile关键词,并不能用于构建happens-before语义,因此在进行多线程程序设计时,要小心使用volatile,不要掉入volatile变量的使用陷阱之中。