C++多線程模型與鎖

C++內存模型

看到《C++0x漫談》系列之:多線程內存模型以前,哪裏會想到一個多線程能夠搞得這麼複雜,各類例子看過以後感受三觀盡毀……程序員沒錯,都是編譯器優化惹的禍。固然,編譯器也是合乎以前的標準,問題在哪裏?規定多線程安全的標準相對缺失。那具體來說到底缺失的標準具體是什麼呢?上面的文章最後只講了「順序一致性」,並無給出詳細的技術上的答案。並且,我仍是有一個疑惑,若是上文中所說的pthread庫等都沒法保證多線程程序的正確性,那麼多人用沒出問題?沒人反應?那Windows/Linux上的C++多線程程序都是怎麼寫的?html

接着,又看到了《程序員的自我修養》中關於加鎖不能保證線程安全的一個錯誤這篇文章。從文章和下面跟帖留言的討論能夠看出:pthread庫是有本身的一套內存可見性的規範,因此保證了程序的正常執行。而若是使用的鎖機制沒有保證這一點,就可能存在所說的加鎖也不能保證線程安全的問題。但劉未鵬文中那個pthread的例子應該也不是假的,這是咱造紙太淺,沒看懂~java

到了C++11具體的內存模型,參見C++11 併發指南七(C++11 內存模型一:介紹)c++

咱們必須對編譯器和 CPU 做出必定的約束才能合理正確地優化你的程序,那麼這個約束是什麼呢?答曰:內存模型。C++程序員要想寫出高性能的多線程程序必須理解內存模型,編譯器會給你的程序作優化(靜態),CPU爲了提高性能也有亂序執行(動態),總之,程序在最終執行時並不會按照你以前的原始代碼順序來執行,所以內存模型是程序員、編譯器,CPU 之間的契約,遵照契約後你們就各自作優化,從而儘量提升程序的性能。C++11 中規定了 6 種訪存次序(Memory Order)程序員

可是具體的六種Memory Order怎樣使用,區別感受仍是沒講清楚,關鍵是沒有例子,等着看到了好的文章再補充~算法

———————————————看了多篇相關文章以後的分割線——————————————————— 感受這玩意兒真不是普通程序猿玩的啊~ 參考以下: c++11 內存模型解讀——簡單清楚。其中最後一段的幾句話摘錄以下:shell

內存模型方面的知識是很難理解,更難以正確使用的,在大多數狀況下使用它而獲得的些少性能優點,已經徹底不值得爲此而帶來的代碼複雜性及可讀性方面的損失,若是你還在猶豫是否要用這些相對底層的東西的時候,就不要用它,猶豫就說明還有其它選擇,不到沒得選擇,都不要親自實現 lock free 相關的東西。編程

漫談C++11多線程內存模型——文中講了「happens-before」概念,但看了圖和例子仍是沒看懂~哎,仍是智商不夠啊~ 淺析C++多線程內存模型——文章很好,講的較爲詳細了。並且他的博客上並行編程系列文章都很好值得一讀。 C++11併發內存模型學習——文章中講了consume,並且介紹了memory_order的幾種類型。安全

信號量與自旋鎖

看了陳皓的相關博客無鎖隊列的實現以後,感受使用CAS啥的高大上。可是看代碼心中難免有些疑惑——自旋操做都是while循環——這是在空耗CPU啊,能高效麼?這前幾天看到C++11已經支持,因此本身寫了個程序看看到底有多高效。因而用Xcode寫了個demo對比atomic_flag和mutex對比測試。100個線程,每一個線程循環累加全局變量10000次。使用了自旋鎖執行時間比使用mutex多不少,CPU使用率很是高,而mutex的CPU基本使用率很低。而Pthreads並行編程之spin lock與mutex性能對比分析這篇文章,測試並解釋了上述現象,提出了自旋鎖和mutex的使用場景:多線程

pthread_spin_lock應該與kernel裏面的spin lock同樣,鎖定的關鍵區域要比較小才能夠。 若是一個線程1得到spin後,另外一個線程2在另外一個CPU busy-wait該spin lock過程, 若是線程2在跑完這次CPU時間後,仍未得到該spin lock,剛說明,線程1鎖的時間太長了。 應該使用mutex,而不該該使用spin lock.併發

其餘參考文章

活鎖的概念 阿姆達爾法則(Amdahl’s Law):整體執行時間T = S + P/N 讀寫鎖的解釋 一個加鎖操做通常須要100個CPU時鐘週期 Doug Lea提到java.util.concurrent庫中一個Non Blocking的算法的實現大概須要1我的年,總共約500行代碼。

——並行編程中的「鎖」難題

多線程程序中操做的原子性 ——彙編仍是很重要的,尤爲是底層相關性較大的領域;此文還介紹了memory location的概念。

相關文章
相關標籤/搜索