Go并发1 - 带着问题去探索Go并发

114 阅读2分钟

关于Go并发的5个问题

1. 在面对并发难题时,感觉无从下手,不知道该用什么并发原语来解决问题。
2.如果多个并发原语都可以解决问题,那么,究竟哪个是最优解呢?比如说是用互斥锁,还是用 Channel。
3.不知道如何编排并发任务。并发编程不像是传统的串行编程,程序的运行存在着很大的不确定性。这个时候,就会面临一个问题,怎么才能让相应的任务按照你设想的流程运行呢?
4.有时候,按照正常理解的并发方式去实现的程序,结果莫名其妙就 panic 或者死锁了,排查起来非常困难。
5.已知的并发原语都不能解决并发问题,程序写起来异常复杂,而且代码混乱,容易出错。

Go并发的两条学习主线

image.png

知识主线
基本并发原语
如Mutex、RWMutex、Waitgroup、Cond、Pool、Context 等标准库中的并发原语,一般用于共享资源场景。
原子操作
Go 标准库中提供的原子操作。原子操作是其它并发原语的基础,我们可以使用原子操作定义自己的并发原语。
Channel
Channel 类型是 Go 语言独特的类型,一般在任务编排中使用。
扩展并发原语
目前来看,Go 开发组不准备在标准库中扩充并发原语了,但是还有一些并发原语应用广泛,比如信号量、SingleFlight、循环栅栏、ErrGroup 等。
分布式并发原语
分布式并发原语是应对大规模的应用程序中并发问题的并发类型。如 Leader 选举、分布式互斥锁、 分布式读写锁、分布式队列等。

学习主线
主要是四大步骤,包括基础用法、实现原理、易错场景、知名项目中的 Bug

打怪升级,Go并发掌握程度的两层衡量标准
第一层是对既有的并发原语进行组合,使用两个、三个或者更多的并发原语去解决问题。、 比如说,我们可以通过信号量和 WaitGroup 组合成一个新的并发原语,这个并发原语可以使用有限个 goroutine 并发处理子任务。

第二层含义是**“无中生有”**,根据已经掌握的并发原语的设计经验,创造出合适的新的并发原语,以应对一些特殊的并发问题。
比如说,标准库中并没有信号量,你可以自己创造出这个类型。