https://github.com/Junedayday/code_reading/blob/master/basic/goroutine.md

Goroutine相关

WaitGroup

  1. 理解WaitGroup的实现 - 核心是CAS的使用
  2. Add与Done应该放在哪? - Add放在Goroutine外,Done放在Goroutine中,逻辑复杂时建议用defer保证调用
  3. WaitGroup适合什么样的场景? - 并发的Goroutine执行的逻辑相同时,否则代码并不简洁,可以采用其它方式

https://mp.weixin.qq.com/s/r9g4ZQLTYJ5QGvBmVIM8YA

分析了源码,我们可以总结如下:

  • Add方法与wait方法不可以并发同时调用,Add方法要在wait方法之前调用.
  • Add()设置的值必须与实际等待的goroutine个数一致,否则会panic.
  • 调用了wait方法后,必须要在wait方法返回以后才能再次重新使用waitGroup,也就是Wait没有返回之前不要在调用Add方法,否则会发生Panic.
  • Done 只是对Add 方法的简单封装,我们可以向 Add方法传入任意负数(需要保证计数器非负)快速将计数器归零以唤醒等待的 Goroutine.
  • waitGroup对象只能有一份,不可以拷贝给其他变量,否则会造成意想不到的Bug.

Context

  1. Context上下文 - 结合Linux操作系统的CPU上下文切换/子进程与父进程进行理解
  2. 如何优雅地使用context - 与select配合使用,管理协程的生命周期
  3. Context的底层实现是什么? - mutexchannel的结合,前者用于初始部分参数,后者用于通信

Channel

  1. channel用于Goroutine间通信时的注意点 - 合理设置channel的size大小 / 正确地关闭channel
  2. 合理地运用channel的发送与接收 - 运用函数传入参数的定义,限制 <- chanchan <-
  3. channel的底层实现 - 环形队列+发送、接收的waiter通知,结合Goroutine的调度思考
  4. 理解并运用channel的阻塞逻辑 - 理解channel的每一对 收与发 之间的逻辑,巧妙地使用
  5. 思考channel嵌套后的实现逻辑 - 理解用 chan chan 是怎么实现 两层通知 的?

sync.Map

  1. sync.Map的核心实现 - 两个map,一个用于写,另一个用于读,这样的设计思想可以类比缓存与数据库
  2. sync.Map的局限性 - 如果写远高于读,dirty->readOnly 这个类似于 刷数据 的频率就比较高,不如直接用 mutex + map 的组合
  3. sync.Map的设计思想 - 保证高频读的无锁结构、空间换时间

sync.Cond

  1. sync.Cond的核心实现 - 通过一个锁,封装了notify 通知的实现,包括了单个通知广播这两种方式
  2. sync.Cond与channel的异同 - channel应用于一收一发的场景,sync.Cond应用于多收一发的场景
  3. sync.Cond的使用探索 - 多从专业社区收集意见 https://github.com/golang/go/issues/21165

sync.Pool

  1. sync.Pool的核心作用 - 读源码,缓存稍后会频繁使用的对象+减轻GC压力
  2. sync.Pool的Put与Get - Put的顺序为local private-> local shared,Get的顺序为 local private -> local shared -> remote shared
  3. 思考sync.Pool应用的核心场景 - 高频使用且生命周期短的对象,且初始化始终一致,如fmt
  4. 探索Go1.13引入victim的作用 - 了解victim cache的机制
  5. 为了使得在多个goroutine中高效的使用goroutine,sync.Pool为每个P(对应CPU)都分配一个本地池,当执行Get或者Put操作的时候,会先将goroutine和某个P的子池关联,再对该子池进行操作。 每个P的子池分为私有对象和共享列表对象,私有对象只能被特定的P访问,共享列表对象可以被任何P访问。因为同一时刻一个P只能执行一个goroutine,所以无需加锁,但是对共享列表对象进行操作时,因为可能有多个goroutine同时操作,所以需要加锁。

atomic

  1. atomic 适用的场景 - 简单、简单、简单!不要将atomic用在复杂的业务逻辑中
  2. atomic.Valuemutex - 学习用两者解决问题的思路
  3. 了解 data race 机制 - atomic可以有效地减少数据竞争