序 1
前言 3
第1 章 Rust 并發(fā)基礎 9
1.1 Rust 中的線程 .10
1.2 作用域線程 14
1.3 共享所有權和引用計數 .17
1.3.1 靜態(tài)對象 .17
1.3.2 泄漏 17
1.3.3 引用計數 .18
1.4 借用和數據競爭 21
1.5 內部可變性 23
1.5.1 Cell .24
1.5.2 RefCell .25
1.5.3 Mutex 和RwLock 26
1.5.4 原子類型 .26
1.5.5 UnsafeCell 27
1.6 線程安全性:Send 和Sync .27
1.7 鎖:互斥鎖和讀寫鎖 30
1.7.1 Rust 的互斥鎖 30
1.7.2 鎖中毒 33
1.7.3 讀寫鎖 35
1.8 等待:線程停放與條件變量 37
1.8.1 線程停放 .37
1.8.2 條件變量 .40
1.9 總結 .42
第2 章 原子性 45
2.1 原子加載和存儲操作 46
2.1.1 示例:停止標志 47
2.1.2 示例:進度報告 48
2.1.3 示例:延遲初始化 .50
2.2 獲取—修改操作 52
2.2.1 示例:多線程進度報告 53
2.2.2 示例:統(tǒng)計 55
2.2.3 示例:ID 分配 .57
2.3 比較—交換操作 59
2.3.1 示例:無溢出的ID 分配 .61
2.3.2 示例:延遲一次性初始化 62
2.4 總結 .64
第3 章 內存順序 67
3.1 重排與優(yōu)化 67
3.2 內存模型69
3.3 happens-before 關系 70
3.4 寬松順序73
3.5 釋放和獲取順序 76
3.5.1 例子:鎖定 80
3.5.2 示例:通過間接方式實現(xiàn)延遲初始化 .82
3.6 消費順序85
3.7 順序一致性順序 87
3.8 柵欄 .88
3.9 常見誤解93
3.10 總結 95
第4 章 構建我們自己的自旋鎖 97
4.1 最簡實現(xiàn)98
4.2 不安全的自旋鎖 .100
4.3 使用鎖衛(wèi)士的安全接口 103
4.4 總結 106
第5 章 構建我們自己的通道 109
5.1 一個基于互斥鎖的簡單通道 .109
5.2 一個不安全的一次性通道 . 111
5.3 通過運行時檢查提高安全性 . 115
5.4 通過類型系統(tǒng)提高安全性 .120
5.5 通過借用避免分配 .125
5.6 阻塞 129
5.7 總結 132
第6 章 構建我們自己的Arc 135
6.1 基礎引用計數 135
6.1.1 測測它 140
6.1.2 修改 .141
6.2 弱指針 .143
6.3 優(yōu)化 150
6.4 總結 158
第7 章 理解處理器 161
7.1 處理器指令 162
7.1.1 加載和存儲 .166
7.1.2 Read-Modify-Write 操作 168
7.1.3 Load-Linked 指令和Store-Conditional 指令 172
7.2 緩存 177
7.2.1 緩存一致性 .178
7.2.2 對性能的影響 .180
7.3 重排 186
7.4 內存順序.188
7.4.1 x86-64:強內存序 189
7.4.2 ARM64:弱內存序 .191
7.4.3 一個實驗 194
7.4.4 內存屏障 196
7.5 總結 198
第8 章 操作系統(tǒng)原語 201
8.1 與內核交互 201
8.2 POSIX .203
8.3 Linux 207
8.3.1 Futex 208
8.3.2 Futex 操作 211
8.3.3 優(yōu)先級繼承Futex 操作 .215
8.4 macOS .216
8.5 Windows .217
8.5.1 重量級內核對象 218
8.5.2 輕量級對象 .218
8.5.3 基于地址的等待 220
8.6 總結 221
第9 章 構建我們自己的鎖 223
9.1 Mutex 225
9.1.1 避免系統(tǒng)調用 .229
9.1.2 進一步優(yōu)化 .231
9.1.3 基準測試 234
9.2 條件變量.237
9.2.1 避免系統(tǒng)調用 .243
9.2.2 避免錯誤喚醒 .245
9.3 讀寫鎖 .248
9.3.1 避免忙循環(huán)的寫入者252
9.3.2 避免寫入者饑餓 255
9.4 總結 258
第10 章 想法和靈感 . 261
10.1 信號量 261
10.2 RCU 262
10.3 無鎖鏈表 264
10.4 隊列鎖 265
10.5 停車位鎖 266
10.6 序列鎖 267
10.7 教學材料 268