互斥锁、Lock()、UnLock(),使用简单但是内部设计很巧妙
一:数据结构
type Mutex struct {
state int32
sema uint32
}
locked:0/1 表示当前锁的状态。
woken:是否有协程被唤醒,0没有1有。
starving:是否饥饿状态。处于饥饿状态时 就不会自旋
waiter:具体数字,表示阻塞等待锁的个数。协程解锁时根据这个来决定是否释放信号量
二:自旋
三:rwmutex
读写互斥锁,mutex的升级版。RLock() RUnlock() Lock() Unlock()
type RWMutex struct {
w Mutex //用于控制多个写锁,获得写锁首先要获取该锁,如果有一个写锁在进行,那么再到来的写锁将会阻塞于此
writerSem uint32 //写阻塞等待的信号量,最后一个读者释放锁时会释放信号量
readerSem uint32 //读阻塞的协程等待的信号量,持有写锁的协程释放锁后会释放信号量
readerCount int32 //记录读者个数
readerWait int32 //记录写阻塞时读者个数
}
3.1写操作如何阻止其他写操作
只有一把锁,写操作是需要获得锁为前提,这个写操作拿到了其他的就拿不到,也就阻止了
3.2写操作如何阻止其他读操作
写的时候 把readcounter 减去 2^30,此时readcounter 为负值,读的时候要去判断这个值就知道是不是处于写状态了
3.3 读操作如何阻止其他写操作
读的时候会把readcounter+1,写的时候要去判断这个值就知道是不是处于读状态了
3.4 读+读不影响
当写操作碰到一堆读操作的时候,为啥不会被饿死??
写到来的时候会记录当前有多少个读操作,读一个值减1,到0的时候 就切到写操作,搞完了再切换读操作