第一章:併發程式設計的挑戰
阿新 • • 發佈:2019-02-16
今天開始閱讀《併發程式設計的藝術》,從這篇部落格開始進行簡單的總結。
併發程式設計的目的是為了讓程式執行的更快,能夠多線操作。但是並不是啟動更多的執行緒,就能讓程式執行的更快。併發程式設計收到上下文切換、死鎖、硬體資源與軟體資源限制等挑戰。
1. 上下文切換
當發生執行緒切換的時候,執行緒的執行環境也要切換(例如暫存器的值,所指向的棧等,程序還涉及到MMU),切換是有代價的(時間)。因此過於頻繁的切換的代價,可能會抹去併發帶來的好處。
如何減少上下文的切換?
- 使用無鎖併發程式設計(多執行緒競爭鎖的時候,引起上下文切換)
- CAS演算法(不需要加鎖來實現同步)
- 使用最少執行緒(避免建立多的多餘執行緒,處於waiting狀態,引起切換)
- 協程(使用單執行緒實現多工的排程,並在單執行緒裡維持多工間的切換)
2.死鎖
使用鎖來解決併發問題是常見的思路,但是不合理的程式碼會引起死鎖。即一組執行緒(程序)都持有資源,並且想要獲取其他執行緒的資源,導致所有執行緒都無限等待的一種情況。
避免死鎖:
- 避免一個執行緒同時獲取多個鎖
- 避免一個執行緒在鎖內同時獲取多個資源
- 使用定時鎖
- 對於資料庫鎖,加鎖和解鎖必須在同一個連線裡,否則就會出現解鎖失敗。
3.資源限制帶來的挑戰
資源的限制有頻寬、IO效能,CPU的處理速度。 軟體資源的限制有資料庫的連線數、socket連線數等。併發程式設計時不應超過資源的限制,超過的結果就是,對資源的利用達到天花板後,增加執行緒並不會提高天花板,只會徒增多個執行緒切換帶來的開銷。
解決硬體資源限制: 使用叢集的方式,例如Hadoop,進行資料的並行。
解決軟體資源限制:使用pool的方式,例如執行緒池,資料庫連線池,避免頻繁的建立和銷燬軟體資源,帶來的額外開銷(記憶體的分配、回收,消耗的時間等)。
總而言之,併發的程度要匹配硬體資源和軟體資源,達到資源的天花板是最大值,再增加併發只會增加切換帶來的開銷,不會增大對資源的並行程度。總體帶來負面效果。