C++并发编程实战(第2版)

C++并发编程实战(第2版)

书名: C++并发编程实战(第2版)作者: 安东尼·威廉姆斯译者: 吴天明出版社: 人民邮电出版社出版日期: 2021-11价格: 89.47页数: 393isbn: 9787115573551评分: 9.5 (豆瓣)评分: 67.2 (微信)

正版购买


内容

这是一本介绍C++并发和多线程编程的深度指南。本书从C++标准程序库的各种工具讲起,介绍线程管控、在线程间共享数据、并发操作的同步、C++内存模型和原子操作等内容。同时,本书还介绍基于锁的并发数据结构、无锁数据结构、并发代码,以及高级线程管理、并行算法函数、多线程应用的测试和除错。本书还通过附录及线上资源提供丰富的补充资料,以帮助读者更完整、细致地掌握C++并发编程的知识脉络。 本书适合需要深入了解C++多线程开发的读者,以及使用C++进行各类软件开发的开发人员、测试人员,还可以作为C++线程库的参考工具书。

作者

安东尼·威廉姆斯(Anthony Williams),C++开发者、顾问、培训师,英国标准协会C++标准组成员,拥有超过20年的C++开发经验,独立编写或合著了众多C++标准委员会文件,为C++11标准引入了线程库,实现了工具“just::thread Pro”(Just Software Solutions公司的产品),并持续致力于开发C++的新特性,以增强C++并发工具集的功能,这两者都遵循C++标准和提案。

目录

第1章你好,C++并发世界 1

1.1 什么是并发 2

1.1.2 并发的方式 4

1.2 为什么使用并发技术 6

1.2.2 为性能而并发:任务并行和数据并行 7

1.3 并发与C++多线程 9

1.3.2 新标准对并发的支持 10

支持并发和并行 10

1.3.5 平台专属的工具 12

实例—“Hello Concurrent World” 12

第2章 线程管控 15

2.1.1 发起线程 16

2.1.3 在出现异常的情况下等待 19

2.2 向线程函数传递参数 23

2.4 在运行时选择线程数量 30

2.6 小结 35

3.1 线程间共享数据的问题 38

3.1.2 防止恶性条件竞争 40

3.2.1 在C++中使用互斥 41

3.2.3 发现接口固有的条件竞争 44

3.2.5 防范死锁的补充准则 53

3.2.7 在不同作用域之间转移互斥归属权 61

3.3 保护共享数据的其他工具 64

3.3.2 保护甚少更新的数据结构 68

3.4 小结 71

4.1 等待事件或等待其他条件 73

4.1.2 利用条件变量构建线程安全的队列 77

4.2.1 从后台任务返回值 83

4.2.3 创建std::promise 88

4.2.5 多个线程一起等待 91

4.3.1 时钟类 94

4.3.3 时间点类 97

4.4 运用同步操作简化代码 101

4.4.2 使用消息传递进行同步 106

4.4.4 后续函数的连锁调用 112

4.4.6 运用std::experimental::when_any()函数等待多个

4.4.7 线程闩和线程卡——并发技术规约提出的新特性 120

4.4.9 基本的线程卡类std::experimental::barrier 122

4.5 小结 125

5.1 内存模型基础 128

5.1.2 对象、内存区域和并发 129

5.2 C++中的原子操作及其类别 131

5.2.2 操作std::atomic_flag 135

5.2.4 操作std::atomic:算术形式的指针运算 139

5.2.6 泛化的std::atomic<>类模板 141

5.3 同步操作和强制次序 145

5.3.2 先行关系 147

5.3.4 释放序列和同步关系 167

5.3.6 凭借原子操作令非原子操作服从内存次序 171

5.4 小结 175

6.1 并发设计的内涵 178

6.2.1 采用锁实现线程安全的栈容器 180

6.2.3 采用精细粒度的锁和条件变量实现线程安全的队列容器 186

6.3.1 采用锁编写线程安全的查找表 198

6.4 小结 208

7.1 定义和推论 210

7.1.2 无锁数据结构 211

7.1.4 无锁数据结构的优点和缺点 212

7.2.1 实现线程安全的无锁栈 214

7.2.3 运用风险指针检测无法回收的节点 223

7.2.5 为无锁栈容器施加内存模型 237

7.3 实现无锁数据结构的原则 254

7.3.2 原则2:使用无锁的内存回收方案 255

7.3.4 原则4:找出忙等循环,协助其他线程 256

第8章 设计并发代码 257

8.1.1 先在线程间切分数据,再开始处理 258

8.1.3 依据工作类别划分任务 263

8.2.1 处理器的数量 266

8.2.3 不经意共享 270

8.2.5 过度任务切换与线程过饱和 271

8.3.1 针对复杂操作的数据划分 272

8.4 设计并发代码时要额外考虑的因素 276

8.4.2 可伸缩性和Amdahl定律 283

8.4.4 借并发特性改进响应能力 286

8.5.1 std::for_each()的并行实现 288

8.5.3 std::partial_sum()的并行实现 295

第9章 高级线程管理 307

9.1.1 最简易可行的线程池 308

9.1.3 等待其他任务完成的任务 313

9.1.5 任务窃取 318

9.2.1 发起一个线程,以及把它中断 323

9.2.3 中断条件变量上的等待 325

9.2.5 中断其他阻塞型等待 330

9.2.7 在应用程序退出时中断后台任务 332

第10章 并行算法函数 335

10.2 执行策略 336

10.2.2 std::execution::sequenced_policy 337

10.2.4 std::execution::parallel_unsequenced_policy 339

10.3.1 并行算法函数的使用范例 342

10.4 小结 346

11.1 与并发相关的错误类型 347

11.1.2 条件竞争 348

11.2.1 审查代码并定位潜在错误 350

11.2.3 设计可测试的代码 353

11.2.5 以特定结构组织多线程的测试代码 357

11.3 小结360

A.1 右值引用 361

A.1.2 右值引用和函数模板 365

A.3 默认函数 368

A.4.1 constexpr关键字和用户定义型别 373

A.4.3 constexpr函数要符合的条件 376

A.5 lambda函数 377

A.7 自动推导变量的型别 386

A.9 类模板的参数推导 389

附录B 各并发程序库的简要

附录C 消息传递程序库和完整