Go语言中的互斥锁(Mutex)和读写锁(RWMutex) 您所在的位置:网站首页 go读写锁和互斥锁 Go语言中的互斥锁(Mutex)和读写锁(RWMutex)

Go语言中的互斥锁(Mutex)和读写锁(RWMutex)

2024-06-14 08:16| 来源: 网络整理| 查看: 265

 Mutex   Mutex结构体 type Mutex struct { state int32 //表示互斥锁的状态,比如是否被锁定等 sema uint32 //表示信号里,协程阻塞等待的信号量,解锁的协程释放信号量从而唤醒等待信号量的协程 }

Locked: 表示Mutex是否已被锁定(1表示已经被锁定)Woken: 表示是否有协程被唤醒(1已有协程唤醒,正在加锁过程中)Starving: 表示Mutex是否处于饥饿状态(1表示饥饿状态,说明有协程阻塞超过1ms)Waiter: 表示阻塞等待锁的协程个数,协程解锁时根据此值来判断是否需要释放洗好了.

协程之间抢锁实际上是抢给Locked赋值的权利,能给Locked值置为1,就说明抢锁成功.抢不到的话就阻塞等待Mutex.sema信号量,一旦持有锁的协程解锁,等到的协程就会被依次唤醒.

Mutex只有两个方法:

Lock()加锁Unlock()解锁 加锁被阻塞以及解锁唤醒协程

自旋(CPU的"PAUSE"指令,CPU空转,什么也不做)

加锁时,如果当前Locked为1,说明该锁由其他协程持有,尝试加锁的协程并不是马上转入阻塞,而是会持续的探测Locked位是否变为0,这个过程即为自旋过程.自旋时间很短,但如果自旋过程中发现锁已经被释放,那么协程可以立即获取锁.(可以避免协程间的切片)

Mutex模式  normal模式

默认情况下,Mutex的模式位normal,该模式下,协程如果加锁不成功不会立即转入阻塞排队,而是判断是否满足自旋条件,如果满足则会启动自旋过程,抢锁.

 starvation模式

自旋过程中能抢到锁的话,说明此时一定有协程释放了锁,释放锁时如果发现有阻塞等待的协程,还会释放一个信号量来唤醒一个等待协程,被唤醒的协程获得CPU开始运行,此时发现锁被抢占,自己再次阻塞,但是如果阻塞时间已经超过1ms,starving将被标记为1(饥饿模式)

饥饿模式下,不会启动自旋过程.

Woken状态

Woken状态用于加锁和解锁过程的通信.

读写锁 type RWMutex struct { w Mutex //用于控制多个写锁,获得写锁首先要获取该锁,如果有一个写锁在进行,那么再到来的写锁将会阻塞于此 writerSem uint32 //写阻塞等待的信号量,最后一个读者释放锁时会释放信号量 readerSem uint32 //读阻塞的协程等待的信号量,持有写锁的协程释放锁后会释放信号量 readerCount int32 //记录读者个数 readerWait int32 //记录写阻塞时读者个数 } 接口定义 RLock(): 读锁定,等待写操作结束(如果有)RUnlock(): 解除读锁定,唤醒等待写操作的协程(如果有)Lock(): 写锁定,与Mutex完全一致,阻塞等待所有读操作结束(如果有)Unlock(): 解除写锁定,与Mutex一致,唤醒因读锁定而被阻塞的协程(如果有)


【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有