锁的基础,go的锁是构建在原子操作和信号锁之上的
原子锁
原子包实现协程的对同一个数据的操作,可以实现原子操作,只能用于简单变量的简单操作,可以把多个操作变成一个操作
sema锁
也叫信号量锁/信号锁
核心是一个uint32值,含义是同时可并发的数量
每一个sema 锁都对应一个SemaRoot结构体
SemaRoot中有一个平衡二又树用于协程排队
获取锁: uint32减一,获取成功
释放锁: uint32加一,释放成功
treap 指针指向sudog
如果uint32为0 获取锁: 协程gopark休眠,进入堆树等待
释放锁: 从堆树中取出一个协程,唤醒
sema锁退化成一个专用休眠队列
sema经常被用作休眠队列