简介

最近在上某在线教育网站的「 Go 进阶训练营(第7期)」课程。这一周是第3周,内容是「 Go 并发编程」。

这周的课程大致包含以下几个主题:

  • go并发(goroutine、调度器和channel)的底层原理
  • go内存模型的底层原理
  • context的底层原理
  • sync包的底层原理
  • go并发编程的最佳实践
  • atomic包的基本用法

课程的课件末尾列出了很多(42篇)要读的 Reference 。但是,这些 Reference 都仅给出了 URL ,而没有提供标题和简介。如果需要围绕特定知识进行阅读会很不方便。

我将在这篇文章里按照主题分别列出这些 URL ,并简单描述每个 URL 的内容。

底层原理:goroutine、调度器、channel

https://morsmachine.dk/go-scheduler go调度器原理

https://www.ardanlabs.com/blog/2014/01/concurrency-goroutines-and-gomaxprocs.html GOMAXPROCS如何影响go协程的并发

https://www.ardanlabs.com/blog/2015/02/scheduler-tracing-in-go.html go调度器追踪(tracing)协程的运行过程

https://medium.com/a-journey-with-go/go-discovery-of-the-trace-package-e5a821743c3c 使用trace包跟踪协程运行

https://medium.com/a-journey-with-go/go-ordering-in-select-statements-fd0ff80fd8d6 go协程 和 select的底层原理

https://medium.com/a-journey-with-go/go-buffered-and-unbuffered-channels-29a107c00268 channel的底层原理

底层原理:go内存模型,happens before

https://golang.org/ref/mem go内存模型,happens before

https://blog.csdn.net/caoshangpa/article/details/78853919 内存屏障 memory barrier

https://people.freebsd.org/~lstewart/articles/cpumemory.pdf CPU缓存和内存的底层设计和影响

https://blog.csdn.net/qcrao/article/details/92759907 内存重排、CPU重排、编译器重排

https://cch123.github.io/ooo/ 内存重排

https://dave.cheney.net/2018/01/06/if-aligned-memory-writes-are-atomic-why-do-we-need-the-sync-atomic-package 原子读写,以及sync/atomic

https://dave.cheney.net/2014/06/27/ice-cream-makers-and-data-races data race的一个例子(冰淇淋maker)

https://www.ardanlabs.com/blog/2014/06/ice-cream-makers-and-data-races-part-ii.html data race的一个例子(冰淇淋maker)关于struct内存布局,判断一致性

https://www.ardanlabs.com/blog/2013/10/my-channel-select-bug.html 和go内存模型有关的select误用。

底层原理:sync包

https://medium.com/a-journey-with-go/go-mutex-and-starvation-3f4f4e75ad50 Mutex模型,Barging,Handoff,Spinning。

https://blogtitle.github.io/go-advanced-concurrency-patterns-part-3-channels/ 底层原理:sync包的Once、Mutex、RWMutex、Pool、Map、WaitGroup、Cond。这也是go channel的一个最佳实践。

底层原理:context

https://medium.com/a-journey-with-go/go-context-and-cancellation-by-propagation-7a808bbc889c context里关于各种各样cancel的原理。

最佳实践:go协程、channel

https://www.ardanlabs.com/blog/2018/11/goroutine-leaks-the-forgotten-sender.html 协程泄漏的例子和解决。

https://www.ardanlabs.com/blog/2019/04/concurrency-trap-2-incomplete-work.html 未完成的工作(Imcomplete work)的例子和解决。

https://dave.cheney.net/practical-go/presentations/qcon-china.html#_concurrency go并发的一些陷阱。

https://blog.golang.org/codelab-share 通过通信来共享内存

https://www.ardanlabs.com/blog/2017/10/the-behavior-of-channels.html 何时、如何使用channel

https://go.dev/blog/io2013-talk-concurrency go channel的误用和解决

https://blog.golang.org/io2012-videos go并发的模式

https://go.dev/blog/concurrency-timeouts go并发模式:Timing out, Moving on

https://go.dev/blog/pipelines go并发模式:pipelines, Cancellation

https://www.ardanlabs.com/blog/2014/02/running-queries-concurrently-against.html go并发访问mongoDB。

https://www.ardanlabs.com/blog/2013/05/thread-pooling-in-go-programming.html 用go实现线程池

https://www.ardanlabs.com/blog/2013/09/pool-go-routines-to-process-task.html 协程池和任务队列的go实现

https://drive.google.com/file/d/1nPdvhB0PutEJzdCq5ms6UI58dp50fcAN/view go并发的实践

https://go.dev/doc/effective_go#concurrency go协程和channel的实践

https://zhuanlan.zhihu.com/p/34417106?hmsr=toutiao.io context的底层原理(因为是二手的所以不看),以及context容易踩的坑

https://talks.golang.org/2014/gotham-context.slide#1 context的创建和cancel的最佳实践

https://medium.com/@cep21/how-to-correctly-use-context-context-in-go-1-7-8f2c0fafdf39 context的最佳实践

最佳实践:context

https://blog.golang.org/context context的基本用法

https://www.ardanlabs.com/blog/2019/09/context-package-semantics-in-go.html context使用的一些语义(context的某些函数的业务含义及用途)

包的使用:atomic

https://medium.com/a-journey-with-go/go-how-to-reduce-lock-contention-with-the-atomic-package-ba3b2664b549 atomic vs Mutex的性能

其他知识

https://www.ardanlabs.com/blog/2014/02/the-nature-of-channels-in-go.html channel的基本用法

https://blog.golang.org/waza-talk 并发和并行的区别

https://golang.org/ref/spec#Channel_types 各种类型的channel的go语法(只读、只写、可读可写)

https://redis.io/topics/persistence redis的BGSAVE和copy-on-write原理

总结

这篇文章大致列出了「 Go 并发编程」各个分支主题的 Reference 的 URL 并附加了关于内容的简短注解。

这些分支主题包含了「底层知识」、「最佳实践」和「包的使用」几种类型,不同的类型应该带着不同的目的去阅读。

在后面的文章中,我会对每个主题的知识点做一些总结。