內容簡介
《C++並發編程實戰》是一本基於C++11新標準的並發和多執行緒編程深度指南。內容包括從std::thread、std::mutex、std::future和std::async等基礎類的使用,到記憶體模型和原子操作、基於鎖和無鎖數據結構的構建,再擴展到並行算法、執行緒管理,**後還介紹了多執行緒代碼的測試工作。本書的附錄部分還對C++11新語言特性中與多執行緒相關的項目進行了簡要的介紹,並提供了C++11執行緒庫的完整參考。
《C++並發編程實戰》適合於需要深入了解C++多執行緒開發的讀者,以及使用C++進行各類軟體開發的開發人員、測試人員。對於使用第三方執行緒庫的讀者,也可以從本書後面的章節中了解到相關的指引和技巧。同時,本書還可以作為C++11執行緒庫的參考工具書。
圖書目錄
第1章 你好,C++並發世界
1.1 什麼是並發 2
1.1.1 計算機系統中的並發 2
1.1.2 並發的途徑 3
1.2 為什麼使用並發 5
1.2.1 為了劃分關注點而使用
並發 5
1.2.2 為了性能而使用並發 6
1.2.3 什麼時候不使用並發 7
1.3 在C++中使用並發和
多執行緒 8
1.3.1 C++多執行緒歷程 8
1.3.2 新標準中的並發支持 9
1.3.3 C++執行緒庫的效率 9
1.3.4 平台相關的工具 10
1.4 開始入門 11
1.5 小結 12
第 2章 管理執行緒
2.1 基本執行緒管理 13
2.1.1 啟動執行緒 14
2.1.2 等待執行緒完成 16
2.1.3 在異常環境下的等待 17
2.1.4 在後台運行執行緒 19
2.2 傳遞參數給執行緒函式 20
2.3 轉移執行緒的所有權 23
2.4 在運行時選擇執行緒
數量 26
2.5 標識執行緒 28
2.6 小結 29
第3章 線上程間共享數據
3.1 執行緒之間共享數據的
問題 32
3.1.1 競爭條件 33
3.1.2 避免有問題的競爭
條件 34
3.2 用互斥元保護共享
數據 35
3.2.1 使用C++中的互斥元 35
3.2.2 為保護共享數據精心組織
代碼 36
3.2.3 發現接口中固有的競爭
條件 38
3.2.4 死鎖:問題和解決方案 44
3.2.5 避免死鎖的進一步
指南 46
3.2.6 用std::unique_lock靈活
鎖定 51
3.2.7 在作用域之間轉移鎖的
所有權 52
3.2.8 鎖定在恰當的粒度 54
3.3 用於共享數據保護的替代工具 56
3.3.1 在初始化時保護共享
數據 56
3.3.2 保護很少更新的數據
結構 59
3.3.3 遞歸鎖 61
3.4 小結 62
第4章 同步並發操作
4.1 等待事件或其他條件 63
4.1.1 用條件變數等待條件 65
4.1.2 使用條件變數建立一個
執行緒安全佇列 67
4.2 使用future等待一次性
事件 71
4.2.1 從後台任務中返回值 72
4.2.2 將任務與future相關聯 74
4.2.3 生成(std::)promise 77
4.2.4 為future保存異常 79
4.2.5 等待自多個執行緒 80
4.3 有時間限制的等待 82
4.3.1 時鐘 83
4.3.2 時間段 84
4.3.3 時間點 85
4.3.4 接受逾時的函式 86
4.4 使用操作同步來簡化
代碼 88
4.4.1 帶有future的函式式
編程 88
4.4.2 具有訊息傳遞的同步
操作 92
4.5 小結 96
第5章 C++記憶體模型和原子類型上操作
5.1 記憶體模型基礎 98
5.1.1 對象和記憶體位置 98
5.1.2 對象、記憶體位置以及
並發 99
5.1.3 修改順序 100
5.2 C++中的原子操作及
類型 100
5.2.1 標準原子類型 101
5.2.2 std::atomic_flag上的
操作 103
5.2.3 基於std::atomic的
操作 105
5.2.4 std::atomic上的操作:指針算術運算 107
5.2.5 標準原子整型的
操作 108
5.2.6 std::atomic<>初級類
模板 109
5.2.7 原子操作的自由函式 111
5.3 同步操作和強制
順序 112
5.3.1 synchronizes-with
關係 114
5.3.2 happens-before關係 114
5.3.3 原子操作的記憶體
順序 116
5.3.4 釋放序列和
synchronizes-with 133
5.3.5 屏障 135
5.3.6 用原子操作排序非原子
操作 137
5.4 小結 138
第6章 設計基於鎖的並發數據結構
6.1 為並發設計的含義是
什麼 141
6.2 基於鎖的並發數據
結構 142
6.2.1 使用鎖的執行緒
安全棧 142
6.2.2 使用鎖和條件變數的執行緒
安全佇列 145
6.2.3 使用細粒度鎖和條件變數的執行緒安全佇列 149
6.3 設計更複雜的基於鎖的
數據結構 160
6.3.1 編寫一個使用鎖的執行緒
安全查找表 160
6.3.2 編寫一個使用鎖的執行緒
安全鍊表 165
6.4 小結 169
第7章 設計無鎖的並發數據結構
7.1 定義和結果 171
7.1.1 非阻塞數據結構的
類型 171
7.1.2 無鎖數據結構 172
7.1.3 無等待的數據結構 172
7.1.4 無鎖數據結構的優點與
缺點 172
7.2 無鎖數據結構的
例子 173
7.2.1 編寫不用鎖的執行緒
安全棧 174
7.2.2 停止惱人的泄漏:在無鎖數據結構中管理記憶體 178
7.2.3 用風險指針檢測不能被
回收的結點 182
7.2.4 使用引用計數檢測
結點 189
7.2.5 將記憶體模型套用到
無鎖棧 194
7.2.6 編寫不用鎖的執行緒安全
佇列 198
7.3 編寫無鎖數據結構的
準則 209
7.3.1 準則:使用std::memory_order_
seq_cst作為原型 210
7.3.2 準則:使用無鎖記憶體回收
模式 210
7.3.3 準則:當心ABA問題 210
7.3.4 準則:識別忙於等待的循環以及輔助其他執行緒 211
7.4 小結 211
第8章 設計並發代碼
8.1 線上程間劃分工作的
技術 214
8.1.1 處理開始前線上程間劃分
數據 214
8.1.2 遞歸地劃分數據 215
8.1.3 以任務類型劃分
工作 219
8.2 影響並發代碼性能的
因素 222
8.2.1 有多少個處理器 222
8.2.2 數據競爭和桌球
快取 223
8.2.3 假共享 225
8.2.4 數據應該多緊密 225
8.2.5 過度訂閱和過多的任務
切換 226
8.3 為多執行緒性能設計數據
結構 226
8.3.1 為複雜操作劃分數組
元素 227
8.3.2 其他數據結構中的數據
訪問方式 228
8.4 為並發設計時的額外
考慮 230
8.4.1 並行算法中的異常
安全 230
8.4.2 可擴展性和阿姆達爾
定律 237
8.4.3 用多執行緒隱藏延遲 238
8.4.4 用並發提高回響性 239
8.5 在實踐中設計並發
代碼 241
8.5.1 std::for_each的並行
實現 241
8.5.2 std::find的並行實現 243
8.5.3 std::partial_sum的並行
實現 248
8.6 總結 256
第9章 高級執行緒管理
9.1 執行緒池 259
9.1.1 **簡單的執行緒池 259
9.1.2 等待提交給執行緒池的
任務 261
9.1.3 等待其他任務的
任務 265
9.1.4 避免工作佇列上的
競爭 267
9.1.5 工作竊取 269
9.2 中斷執行緒 273
9.2.1 啟動和中斷另一個
執行緒 274
9.2.2 檢測一個執行緒是否被
中斷 275
9.2.3 中斷等待條件變數 276
9.2.4 中斷在std::condition_variable_ any上的等待 279
9.2.5 中斷其他阻塞調用 281
9.2.6 處理中斷 281
9.2.7 在套用退出時中斷後台
任務 282
9.3 總結 284
第 10章 多執行緒套用的測試與調試
10.1 並發相關錯誤的
類型 285
10.1.1 不必要的阻塞 286
10.1.2 競爭條件 286
10.2 定位並發相關的錯誤的
技巧 288
10.2.1 審閱代碼以定位潛在的
錯誤 288
10.2.2 通過測試定位並發相關的
錯誤 290
10.2.3 可測試性設計 291
10.2.4 多執行緒測試技術 292
10.2.5 構建多執行緒的測試
代碼 295
10.2.6 測試多執行緒代碼的
性能 297
10.3 總結 298
附錄A 附錄A C++11部分
語言特性簡明
參考 299
附錄B 並發類庫