互斥锁(Mutex)

一.Mutex 实现

          Mutex 主要由CAS指定,自选,和解锁信号量实现。

二.Mutex 排队模式

        当Mutex被一个goroutine获得锁占用时,其他的goroutine会进入自旋状态或者进入等待队列(休眠状态),等待解锁信号量唤醒。

        而这里的排队等待模式又分为了两种,一种是正常模式,一种是饥饿模式。

正常模式:新请求的goroutine进入自旋时是仍然拥有cpu的,相对于等待解锁信号量的goroutine更容易获得锁。所以被唤醒的goroutine很大几率在锁竞争中失败。

饥饿模式:而当等待解锁信号量的那些goroutine等待的时间超过1ms后,而这些goroutine则是进入了饥饿模式,就会放到等待队列的队头,这个时候如果mutex 处于locked状态,则Mutex也会进入饥饿状态。当解锁信号量到来时,Mutex处于饥饿状态则会将锁优先发给队头的goroutine。

三.Goroutine 的饥饿与 Mutex 饥饿之间的关系?

        Goroutine 的状态跟 Mutex 的是息息相关的。只有在 Goroutine 是饥饿状态下,才有可能给 Mutex 设置成饥饿状态。在 Mutex 是饥饿状态时,才有可能让饥饿的 Goroutine 优先获取到锁。不过需要注意的是,触发 Mutex 饥饿的 Goroutine 并不一定获取锁,有可能被其他的饥饿的 Goroutine 截胡。

四.Goroutine 能够加锁成功的情况

Mutex 没有被 Goroutine 占用 Mutex.state = 0, 这种情况下一定能获取到锁. 例如: 第一个 Goroutine 获取到锁
还有一种情况 Goroutine有可能加锁成功:

  1. 当前 Mutex 不是饥饿状态, 也不是 Locked 状态, 尝试 CAS 加锁时, Mutex 的值还没有被其他 Goroutine 改变, 当前 Goroutine 才能加锁成功.
  2. 某个 Goroutine 刚好被唤醒后, 重新获取 Mutex, 这个时候 Mutex 处于饥饿状态. 因为这个时候只唤醒了饥饿的 Goroutine, 其他的 Goroutine 都在排队中, 没有其他 Goroutine 来竞争 Mutex, 所以能直接加锁成功

参考文献:

这可能是最容易理解的 Go Mutex 源码剖析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值