最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入理解線程安全與Singleton

 更新時間:2013年09月18日 09:22:42   作者:  
在編譯器未優(yōu)化的情況下順序如下:1.new operator分配適當?shù)膬却妫?.在分配的內存上構造Singleton對象;3.內存地址賦值給_instance

線程安全是個非常棘手的問題。即使你合理的使用了鎖(lock),依然可能不會產生預期的效果。
讓我們來看看貌似合理的代碼

復制代碼 代碼如下:

X=0;
Thread 1                   Thread2
lock();  lock();
x++;    x++;
unlock();  unlock();

你會認為執(zhí)行完這兩個線程之后,X的一定值等于2?沒錯,因為lock()和unlock()的保護,x++的執(zhí)行并不會被打斷。(為什么++操作會被多線程給擾亂呢?原因就在于++操作在被編譯成匯編之后對應到了多條匯編代碼。)但是,編譯器卻可能因為自作聰明的優(yōu)化,把x放到register里面(因為寄存器速度快嘛),也就是說當Thread1執(zhí)行完x++之后,被Thread2打斷,但是1這個值只保存到了寄存器x里,沒有寫入內存中的x變量里。隨后Thread2執(zhí)行完成后,內存中x的值等于1,此時,Thread1再執(zhí)行完,內存中的x又被寫入為1.
原來都是編譯器倒得鬼!

再看一個例子

復制代碼 代碼如下:

x=y=0;
Thread1                        Thread2
y=1;                                x=1;
r1=x;                               r2=y;

當你拍胸脯向崇拜你的MM保證說:r1或者r2至少有一個為1的時候,可惜編譯器又再一次的站到了你的對立面。

原因是早在十幾年前還是幾十年前,編譯器就有了這么一種優(yōu)化機制,為了提高效率而交換指令的序列。所以上面的代碼到了可能變成了這樣:

復制代碼 代碼如下:

x=y=0;
Thread1                        Thread2
r1=x;                             r2=y;
y=1;                              x=1;                


知道你錯了吧~還好我們還有volatile:
1. 阻止編譯器為了提高速度將變量緩存寄存到寄存器內而不寫回內存。
2. 阻止編譯器調整操作指令序列

哈哈,可惜道高一尺,魔高一丈。CPU動態(tài)調度的功能,CPU可以交換指令序列。volatile幫不了你,但宙斯大帝為我們發(fā)明了:barrier指令(這是一個CPU的指令)能夠幫組我們阻止CPU調整操作指令序列。
好想目前我們解決了現(xiàn)場安全的問題了。

有一個著名的與換序有關的問題來至于Singleton模式的double-check。代碼大概是這樣子的:

復制代碼 代碼如下:

volatile Singleton* Singleton::_instance = 0;

復制代碼 代碼如下:

static Singleton& Instance() {
      if (0 == _instance) {
          Lock lock(_mutex);
          if (0 == _instance) {
              _instance = new Singleton();
              atexit(Destroy);
          }
      }
      return *_instance;
 }

簡單的說,編譯器為了效率可能會重排指令的執(zhí)行順序(compiler-based reorderings)。
看這一行代碼:
_instance = new Singleton();

在編譯器未優(yōu)化的情況下順序如下:
1.new operator分配適當?shù)膬却妫?BR>2.在分配的內存上構造Singleton對象;
3.內存地址賦值給_instance。

但是當編譯器優(yōu)化后執(zhí)行順序可能如下:
1.new operator分配適當?shù)膬却妫?BR>2.內存地址賦值給_instance;
3.在分配的內存上構造Singleton對象。

當編譯器優(yōu)化后,如果線程一執(zhí)行到2后被掛起。線程二開始執(zhí)行并發(fā)現(xiàn)0 == _instance為false,于是直接return,而這時Singleton對象可能還未構造完成,后果...

相關文章

  • C++解析obj模型文件方法介紹

    C++解析obj模型文件方法介紹

    由于本人打算使用Assimp來加載模型,這里記錄一下tinyobjloader庫的使用。之前也研究過fbxsdk,除了骨骼動畫暫未讀取外,代碼自認為還算可靠
    2022-09-09
  • C++實現(xiàn)LeetCode(29.兩數(shù)相除)

    C++實現(xiàn)LeetCode(29.兩數(shù)相除)

    這篇文章主要介紹了C++實現(xiàn)LeetCode(29.兩數(shù)相除),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下
    2021-07-07
  • 利用c++寫一個簡單的推箱子小游戲

    利用c++寫一個簡單的推箱子小游戲

    推箱子想必是很多人童年時期的經典游戲,我們依舊能記得抱個老人機娛樂的場景,下面這篇文章主要給大家介紹了關于如何利用c++寫一個簡單的推箱子小游戲的相關資料,需要的朋友可以參考下
    2021-09-09
  • 基于C語言實現(xiàn)簡單的五子棋游戲

    基于C語言實現(xiàn)簡單的五子棋游戲

    這篇文章主要為大家詳細介紹了基于C語言實現(xiàn)簡單的五子棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C語言庫函數(shù)qsort的使用詳解

    C語言庫函數(shù)qsort的使用詳解

    C語言庫函數(shù)中的qsort的是一個回調函數(shù),回調函數(shù)就是一個通過函數(shù)指針調用的函數(shù),這篇文章主要介紹了C語言庫函數(shù)qsort的使用,需要的朋友可以參考下
    2022-06-06
  • 弦圖ZOJ 1015 Fishing Net 判定方法

    弦圖ZOJ 1015 Fishing Net 判定方法

    弦圖,算法完全按照CDQ的PPT上給的最大勢算法(MCS)完美消除序列..需要的朋友可以參考下
    2012-11-11
  • C++位操作的常見用法小結

    C++位操作的常見用法小結

    這篇文章主要介紹了C++位操作的常見用法,包括了判斷奇偶、交換兩個數(shù)、正負轉換、求絕對值等,需要的朋友可以參考下
    2014-09-09
  • C++應用實現(xiàn)簡易五子棋游戲

    C++應用實現(xiàn)簡易五子棋游戲

    這篇文章主要為大家詳細介紹了C++應用實現(xiàn)簡易五子棋游戲,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C++中的類擴展之繼承和組合詳解

    C++中的類擴展之繼承和組合詳解

    在C++中,類擴展可以通過繼承、組合和裝飾模式實現(xiàn)。繼承可以實現(xiàn)對已有類的修改和擴展,組合可以增加新的功能,裝飾模式則能夠在不改變原類的情況下為其添加新的功能。這些技術在C++程序設計中應用廣泛,提高了程序的可擴展性和可維護性
    2023-04-04
  • C++中的多態(tài)與多重繼承實現(xiàn)與Java的區(qū)別

    C++中的多態(tài)與多重繼承實現(xiàn)與Java的區(qū)別

    這篇文章主要介紹了C++中的多態(tài)與多重繼承實現(xiàn)與Java的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2020-03-03

最新評論

海城市| 武山县| 伊宁县| 庆元县| 阿荣旗| 田林县| 南投县| 扶余县| 佛冈县| 龙陵县| 文昌市| 麻江县| 威宁| 淄博市| 新闻| 邵武市| 淄博市| 丹阳市| 蓬溪县| 江华| 友谊县| 阳东县| 尼玛县| 青阳县| 互助| 故城县| 金坛市| 新源县| 松江区| 洮南市| 科技| 抚宁县| 涟源市| 元氏县| 天全县| 金坛市| 漳平市| 镇巴县| 乐安县| 南宫市| 图片|