C++ const 成員函數 最好是多線程安全的

  • 總覽

    • 核心

      • const修飾的成員函數理論上說是不會修改值的.

      • 如果有成員mutable,則是可以修改.

      • 修改就會遇到資源競爭和多線程安全問題。

    • 多線程安全

      • 只有多線程共享的數據纔會有多線程安全問題。

      • 即一致性問題,其實對於某些數據,只有整個獨佔才能保證多線程安全。

      • 或者確認不共享,只有一個線程串行使用。

    • 文章內容

      • 多線程安全函數的案例不太靠譜。

      • 不過是針對C++98C++11來將,還是有一點內容的。

  • 多線程安全

    • 讀寫模式

      • 採用volatile和內存屏障的形式保證一致性.

      • 修改方用函數修改了之後就寫屏障使生效。讀取方則短暫用讀屏障,保證數據有效。

      • 適合特別短的代碼等待。長等待需要用鎖,讓線程睡眠,以讓出資源,而不是空轉。

      • volatilebarrier一般是在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::atomicmutex效率高,使用場景是單個標量或者某個內存區間的值.

  • 發表評論
    所有評論
    還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
    相關文章