深入理解Go并发编程:从原理到实践,看这本就够了
  • 推荐0
  • 收藏0
  • 浏览160

深入理解Go并发编程:从原理到实践,看这本就够了

晁岳攀(@鸟窝) (译者) 张月萍 (责任编辑)

  • 书  号:9787121466465
  • 出版日期:2023-11-01
  • 页  数:
  • 开  本:
  • 出版状态:上市销售
  • 维护人:博文小编
《深入理解Go并发编程:从原理到实践,看这本就够了》分为四大部分。第1部分包括第1~13章,主要介绍Go标准库的同步原语,包括互斥锁Mutex、读写锁RWMutex、WaitGroup、条件变量Cond、Once、Map、Pool、Context、channel等,以及最新的原子操作知识,其中重点介绍了channel,最后还介绍了Go的内存模 型。第2部分包括第14~18章,主要介绍Go官方的扩展库和第三方的同步原语,包括信号量、SingleFlight、CyclicBarrier、分组操作库、限流库等。第3部分包括第19章,主要介绍基于etcd的分布式同步(并发)原语。第4部分包括第20章和第21章,主要归纳总结Go的并发模式,并尝试使用本书介绍的同步原语解决经典的并发问题。
《深入理解Go并发编程:从原理到实践,看这本就够了》主要面向的是已经具有Go软件编程开发经验的工程师、基础架构软件开发工程师和架构师,需要初步和深入了解Go并发编程的相关知识,设计和实现高并发的基础软件与分布式系统的专业人员,以及对Go并发感兴趣的读者。
以漫画与通俗易懂的语言阐释复杂的并发概念,让读者在轻松愉悦中掌握Go语言强大的并发能力。一线互联网大厂名家之作。
晁岳攀(@鸟窝),rpcx微服务框架作者,Go语言布道师,技术专栏作家。
历时五年,本书终于和读者见面了。
五年,不长也不短。五年,可以让我有充足的时间来沉淀、挖掘和整理Go并发相关知识,为读者呈现一本全面且深入的Go并发知识的书。五年来,相关的Go并发知识也在不断地更新,比如Go内存模型的重新定义、atomic包更新,以及互斥锁和读写锁终于加上了TryLock 方法等,对这些同步原语内部的实现也有优化,相关的最新变动也都体现在本书中。
从 2018年开始,我就有意地梳理Go并发编程的知识。2019年,在GopherChina大会上做了第一次分享,后来又在滴滴出行做过专门的研讨课,再后来,我在“极客时间”上做了一个《Go并发编程实战课》专栏,大家反映也比较好。
其实,我很早就想把“极客时间”上的专栏内容整理出来,再加上这几年我对Go并发编程的新的理解和总结,把它打造成一本全面且深入的Go并发编程的书。Go非常适合并发编程,学习Go语言的人感受最深,但是熟练掌握并发编程并不是一件简单的事情,比如知名的Go生态圈的项目,包括Go语言本身,也都出现过很多并发编程的错误。有些书也介绍了Go标准库的几个同步原语,并简单介绍了其使用方法,但是读者觉得不过瘾。所以,我很想尽快将这些内容整理成书,但是一拖就是三四年,“忙”是我用来解释这本书现在才出版的一个借口,“迟疑”才是我一拖再拖的原因。
我有两个迟疑的点:一是我一直在思考,当前我整理出来的Go并发知识是否已经足够全面?我不想出一本关于Go并发编程的书,只是介绍Go并发编程的部分知识,我想系统地覆盖Go并发编程的各个方面,让想学习Go并发编程的读者看这一本书就足够了。所以,这几年我也一直在整理、分析和补充Go并发编程的资料,现在终于到了它“出山”的时候。
二是我有点儿个人化。我期望这本书读者阅读起来非常舒服、有条理。多年前我也出过书,这么多年我也阅读过很多计算机方面的书。我个人觉得书籍的排版、样式、插图、颜色非常影响读者的读书兴趣,我期望这本书能够有良好的排版、舒服的字体和间距、漂亮的插图,并且彩色印刷。我夫人经常嘲笑我这是买椟还珠,但是我还是期待能够遇到与我的这种执念一致的“有缘人”,直到看到《深入理解Linux网络》这本书,通过作者彦飞认识了知名的出版策划人姚新军老师,一拍即合,本书才得以出版。我个人虽然没有美术细胞,但是我从读者的角度希望本书能够以Gopher卡通的形象,最好以中国传统古典风格设计插图。我看了相关的插图和排版,我个人非常喜欢,相信读者阅读起来也会觉得妙趣横生。
当然,为避免“金玉其外,败絮其中”的结局,本书还是致力于干货的介绍,也不枉读者送我“鸟窝出品,必是干货”的称号。本书内容经过仔细的设计,有清晰的脉络可以遵循,内容由浅入深,适合各层次的Go语言爱好者学习,甚至买回来当一本工具书备查也是不错的。

本书特色
● 全面。本书详细介绍了Go标准库中的每一个同步原语,并且补充介绍了Go官方扩展库的同步原语,以及很多第三方的并发库。本书还全面介绍了基于etcd的分布式同步原语,读者在开发分布式程序的时候它很有参考价值。本书还梳理了Go并发模式,读者可以系统性地了解采用并发模式要解决的问题。
● 由浅入深。每个同步原语一开始都会介绍其使用场景和基本的使用方法,很多同步原语都会介绍其实现,读者可以深入了解同步原语背后的原理。书中有作者多年开发经验的总结和梳理,让读者少走弯路。
● 实战。书中包含大量的示例,独创性地梳理了同步原语使用陷阱,还专门列出了知名项目如Kubernetes、Docker、gRPC等项目中出现的并发错误,让读者切身感受到知名项目的有经验的Go程序员也会犯的错。
● 独立。各章之间没有依赖性,每一章都是独立的,读者可以从任意一章开始进行学习。正如“极客时间”的一位读者所说,课程需要反复学几遍才能理解透,所以希望读者也能勤翻一翻本书,多学习几遍,把相关知识掌握透彻。

读者对象
这是一本专门讲解Go并发编程的书。虽然本书面对的是Go初级、中级、高级的程序员,但还是希望读者有基本的Go语言知识,至少要花半天时间先学习一下Go语言的基本编程知识,因为我在一些场合听到其他语言的程序员说半天就可以掌握Go语言了(当然也可以看看其他编程语言的程序,和其他语言的并发编程做一个对比,很多知识都是相通的,可以借鉴)。
任何想使用Go语言进行编程的朋友,无论是在校的学生,还是企业中有志于使用
Go语言编程的程序员,建议都看一看本书。

目录

第1章 Go并发编程和调度器
1.1 Go特别适合并发编程
1.2 并发 vs 并行
1.3 阿姆达尔定律:并发编程优化是有上限的
1.4 Go并发并不一定最快
1.5 Go运行时调度器

第2章 互斥锁Mutex
2.1 竞争条件与数据竞争
2.2 Mutex的用法
2.2.1 一个并发问题
2.2.2 Mutex的使用
2.2.3 地道的用法
2.3 检查程序中的数据竞争
2.4 Mutex的历史实现
2.4.1 初始版本
2.4.2 多给新的 goroutine 一些机会
2.4.3 多给竞争者一些机会
2.4.4 解决饥饿问题
2.4.5 TryLock
2.5 Mutex的使用陷阱
2.5.1 误写
2.5.2 死锁
2.5.3 锁重入
2.5.4 复制锁
2.6 Mutex的扩展
2.6.1 可重入锁
2.6.2 支持并发 map
2.6.3 封装值

第3章 读写锁 RWMutex
3.1 读写锁的使用场景
3.2 读写锁的使用方法
3.3 读写锁的实现
3.3.1 RLock的实现
3.3.2 RUnlock的实现
3.3.3 Lock的实现
3.3.4 Unlock的实现
3.3.5 TryLock的实现
3.3.6 TryRLock的实现
3.4 读写锁的使用陷阱
3.4.1 锁重入
3.4.2 死锁
3.4.3 发现死锁
3.5 读写锁的扩展

第4章 任务编排好帮手 WaitGroup
4.1 WaitGroup的使用方法
4.2 WaitGroup的实现
4.3 WaitGroup的使用陷阱
4.3.1 Add 方法调用的时机不对
4.3.2 计数器的值为负数
4.3.3 错误的调用 Add的时机
4.3.4 知名项目中关于 WaitGroup 使用的 bug
4.4 WaitGroup的扩展
4.5 noCopy:辅助 vet 检查

第5章 条件变量 Cond
5.1 Cond的使用方法
5.2 Cond的实现
5.3 Cond的使用陷阱
5.3.1 调用 Wait 时没有加锁
5.3.2 唤醒之后不检查判断条件
5.4 在实际项目中使用 Cond的例子

第6章 单例化利器 Once
6.1 Once的使用方法
6.2 Once的实现
6.3 Once的使用陷阱
6.3.1 死锁
6.3.2 未初始化

第7章 并发 map
7.1 线程安全的 map
7.1.1 使用 map的两种常见错误
7.1.2 加读写锁:扩展 map,支持并发读/写
7.2 sync.Map的使用方法
7.3 sync.Map的实现
7.3.1 Swap 方法
7.3.2 Load 方法
7.3.3 Delete 方法
7.4 分片加锁:更高效的并发map
7.5 lock-free map

第8章 池 Pool
8.1 sync.Pool的使用方法
8.2 sync.Pool的实现
8.2.1 Get 方法的实现
8.2.2 Put 方法的实现
8.3 sync.Pool的使用陷阱
8.4 连接池
8.4.1 标准库中的 HTTP Client 池
8.4.2 数据库连接池
8.4.3 TCP 连 接池
8.4.4 Memcached Client 连接池
8.4.5 net/rpc 中的 Request/Response 对象池
8.5 goroutine/worker 池

第9章 不止是上下文:Context
9.1 Context的发展历史
9.2 Context的使用方法
9.2.1 基本用法
9.2.2 传递上下文
9.2.3 可撤销的上下文
9.2.4 带超时功能的上下文
9.3 Context 实战
9.4 Context的使用陷阱
9.5 Context的实现
9.5.1 WithValue的实现
9.5.2 WithCancel的实现
9.5.3 WithDeadline的实现

第10章 原子操作

10.1 原子操作的基础知识
10.2 原子操作的使用场景
10.3 atomic 提供的函数和类型
10.3.1 AddXXX函数
10.3.2 CompareAndSwapXXX函数
10.3.3 SwapXXX函数
10.3.4 LoadXXX函数
10.3.5 StoreXXX函数
10.3.6 Value 类型
10.3.7 Bool、Int32、Int64、Pointer、Uint32、Uint64、Uintptr
10.4 uber-go/atomic 库
10.5 lock-free 队列的实现
10.6 原子性和可见性

第11章 channel 基础:另辟蹊径解决并发问题

11.1 channel的历史
11.2 channel的应用场景
11.3 channel的基本用法
11.4 channel的实现
11.4.1 channel的数据结构
11.4.2 初始化
11.4.3 发送数据
11.4.4 接收数据
11.4.5 关闭 channel
11.5 channel的使用陷阱 / 224
11.5.1 panic 和 goroutine 泄漏
11.5.2 知名项目踩过的坑

第12章 channel的内部实现和陷阱
12.1 使用反射操作 select 和 channel
12.2 channel的应用场景


第13章 Go内存模型
13.1 指令重排和可见性的问题
13.2 sequenced before、synchronized before 和 happens before
13.3 各种同步原语的同步保证
13.3.1 初始化
13.3.2 goroutine的运行
13.3.3 channel
13.3.4 锁(Mutex 和 RWMutex)
13.3.5 Once
13.3.6 WaitGroup
13.3.7 atomic操作
13.3.8 Finalizer、sync.Cond、sync.Map 和 sync.Pool
13.4 不正确的同步

第14章 信号量 Semaphore
14.1 什么是信号量
14.1.1 P/V 操作
14.1.2 信号量和互斥锁的区别与联系
14.2 信号量的 channel 实现
14.3 Go官方的信号量实现
14.4 使用信号量的常见错误

第15章 缓解压力利器 SingleFlight
15.1 SingleFlight的实现
15.2 SingleFlight的使用场景

第16章 循环屏障 CyclicBarrier
16.1 CyclicBarrier的使用场景
16.2 CyclicBarrier的实现
16.3 使用 CyclicBarrier的例子

第17章 分组操作
17.1 ErrGroup
17.1.1 ErrGroup的基本用法
17.1.2 ErrGroup 使用示例
17.2 其他实用的 Group 同步原语
17.2.1 SizedGroup/ErrSizedGroup
17.2.2 gollback
17.2.3 Hunch
17.2.4 schedgroup

第18章 限流
18.1 基于令牌桶实现的限流库
18.1.1 x/time/rate
18.1.2 juju/ratelimit
18.2 基于漏桶实现的限流库
18.3 分布式限流

第19章 Go并发编程和调度器
19.1 Leader 选举
19.1.1 选举
19.1.2 查询
19.1.3 监控
19.2 锁 Locker
19.3 互斥锁 Mutex
19.4 读写锁 RWMutex
19.5 分布式队列和优先级队列
19.6 分布式屏障 / 340
19.7 计数型屏障 / 342
19.8 软件事务内存

第20章 并发模式
20.1 并发模式概述
20.2 半异步 / 半同步模式
20.3 活动对象模式
20.4 断路器模式
20.5 截止时间和超时模式
20.6 回避模式
20.7 双重检查模式
20.8 保护式挂起模式
20.9 核反应模式
20.10 调度器模式
20.11 反应器模式
20.12 Proactor模式
20.13 percpu模式
20.14 多进程模式

第21章 经典并发问题解析
21.1 哲学家就餐问题
21.1.1 模拟哲学家就餐问题
21.1.2 解法一:限制就餐人数
21.1.3 解法二:奇偶处理方法
21.1.4 解法三:资源分级
21.1.5 解法四:引入服务生
21.2 理发师问题
21.2.1 使用 sync.Cond 解决理发师问题
21.2.2 使用 channel 实现信号量
21.2.3 有多个理发师的情况
21.3 水工厂问题
21.4 fizz buzz 问题
21.4.1 将并发转为串行
21.4.2 使用同一个channel
21.4.3 使用CyclicBarrier

读者评论