總覽
核心
const
修飾的成員函數理論上說是不會修改值的.如果有成員
mutable
,則是可以修改.修改就會遇到資源競爭和多線程安全問題。
多線程安全
只有多線程共享的數據纔會有多線程安全問題。
即一致性問題,其實對於某些數據,只有整個獨佔才能保證多線程安全。
或者確認不共享,只有一個線程串行使用。
文章內容
多線程安全函數的案例不太靠譜。
不過是針對
C++98
和C++11
來將,還是有一點內容的。
多線程安全
讀寫模式
採用
volatile
和內存屏障的形式保證一致性.修改方用函數修改了之後就寫屏障使生效。讀取方則短暫用讀屏障,保證數據有效。
適合特別短的代碼等待。長等待需要用鎖,讓線程睡眠,以讓出資源,而不是空轉。
volatile
和barrier
一般是在C
語言裏面使用.統計模式
atomic
類對基本類型實現原子操作. 效率沒有上面的高,不過更安全可靠.長任務模式
對於與需要常事件處理並佔用一系列資源的情況. 需要用互斥。
mutex,sem,condition
等.
C++11
簡介
支持了函數聲明爲
const
,表示函數不會修改類的成員數據,const
類型.這類修飾表明了不會在函數中修改,不保證其他不會修改.
僅僅是限制自身不會對內容進行修改.
修飾目的
用於多線程安全,雖然可能也會發生修改.
但是語義上不能修改. 而自己開發的時候 也需要注意.
雖然 也可以通過
mutable
修飾變量可修改.
const
函數的本質
普通函數,第一個參數是變量指針,第二三參數是其他.
函數只能保障自己不會修改輸入數據,即
obj
對象.發現問題
編譯階段發現問題。
可以較早發現這類錯誤做法。
主要是不修改當前類的值。
案例
class T { public: void cool() const { x = 1; } public: mutable int x{0}; }; int main() { T d; d.cool(); }
這類是可以的,但是修改了值,就存在競爭問題。
只讀一般就不存在資源競爭問題。
競爭的原因
CPU
緩存一致性導致讀寫數據不對。不修改,只讀就不存在問題。對共享數據改就存在問題。
總結
建議
const
儘量做到多線程安全,即不修改數據.
std::atomic
比mutex
效率高,使用場景是單個標量或者某個內存區間的值.