1. 程式人生 > >C++——volatile關鍵字的學習

C++——volatile關鍵字的學習

建議 目的 類型 arc memory 處理 c++ lang 基於

首先聲明一點,本文是關於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變量的使用陷阱之中。

C++——volatile關鍵字的學習