有沒有關於多線程同步的經驗,或者書籍推薦?

每次線程數一多,需要同步的地方多了,就頭昏腦漲。

各位同仁們有什麼經驗之談,或者好的博客/書籍推薦嗎?


Synchronization (Windows)

把這下面的字都精讀了。我當初也是這麼做,也才花了兩個月,所以十分有可行性。


High Performance Computing: Training

POSIX Threads Programming

Message Passing Interface (MPI)

OpenMP


為什麼會這樣,原因其實很簡單,因為傳統的多線程同步的方式存在根本性的問題,就是抽象的層次太低了。傳統鎖互斥(PV操作)把運行的調度剝離開,期望藉助於一個通用的手段來解決所有的同步問題,但在面臨大規模代碼組織結構的情況下,不僅是效率低下,而且代碼也更複雜了。

比如,上面有知友就提議加大鎖的力度,這自然是避免錯漏的一個終結方案,但反過來,更多的鎖,更多的互斥/臨界區的出現,問題反而越是朝著複雜的方向發展。

在現實這個實際的並行世界裡,反而很少遇到這個問題,沒有人會因為讀一本書和喝一杯水這兩件並行的事情把自己搞的支離破碎,因為控制行為的大腦的抽象層次在做這兩件事之上,無論你的行為看起來怎麼並行,他還是會把一系列的動作串的很好。

類似在思考編程中要處理的事件時,任意切割中間的某一個節點,你都可以安排好其先後所發生的事和應有的反應,當然可能只是其中一種路徑,但絕不會出錯。然後你也希望程序像你安排的那樣,選擇一條穩妥的道路前進,結果你發現,因為並行你無法決定代碼的流程,從而無法將頭腦中的安排付諸實施。

所以,這是寫代碼語言描述能力的問題,而不是同步本身多麼難,傳統的語義根本不允許你按照大腦的思維方式去安排代碼的運行,或者要不放棄並行本身。

當然並行邏輯本身對人類大腦而言還是非常難的,但在一定抽象層次上,邏輯可以簡化到一定層度時,這種並行行為是容易被安排過來的。或者說把該同步的同步起來,該串的串起來,只在必要的時候有克制的使用一些鎖互斥或者選擇並行數據結構,這樣世界會美好的多。

所以才有windows消息循環,libevent,node.js,actor,等等各種本質串列的東西在下面墊底,基本上所有的GUI框架(因為輸入是絕對無法預期的事件),都是一個main loop類似的東西在驅動。深入到操作系統底層,所有調度器也是這樣。甚至號稱天生可以並行的函數式語言,真正編程需要同步的時候,也還是靠這個。

當然,這只是建議,我在另一個問題中展示了一種強有力的描述方法,但暫時沒有實際語言/庫提供,僅供參考:python二維數組按照某一列進行篩選統計?


The Java Memory Model

慢慢領悟


  1. 分析問題,確定自己要解決的問題。並行還是並發,SIMD 還是管線網路,選對正確的模型是第一步的。
  2. 如果你能在 C++ 中做到基本沒有內存泄露,那麼把對於對象的生存期管理方法套用在競爭狀態管理上,大致也就夠了。

  3. 從設計角度說,共享內容越少,並發程度越高,程序提速的可能性越高 Amdahl"s law (不餓看下面那個在 Python 二維數組裡胡扯的)

  4. 當共享狀態不可避免的時候,首先選擇消息傳遞,實在沒有辦法再選擇共享內存加鎖。

  5. 用儘可能高級的抽象:能用 MessageQueue 就不要手寫 socket,能用 socket 就不要用共享內存+鎖
  6. 仔細分析邏輯

  7. 記住一點:如果要用鎖,只能用於保護共享資源,而不是保護代碼段


如果java的話:

並發編程網

《深入淺出 Java Concurrency》

並發 在InfoQ上的內容


推薦閱讀:

為什麼有很多程序員喜歡穿衛衣寫代碼,而且還不把帽子放下來?
如何自己實現一個關係型資料庫?
開發流氓程序是一種怎樣的體驗?
合作同事代碼寫得很爛怎麼辦?
AWS、Azure等國外雲計算如何遷移到國內阿里雲上?

TAG:編程 | 計算機 | 代碼 | C | 多線程 |