go-mutex的模式

go-mutex的模式
  • go-mutex的模式
    • 1. 正常模式
    • 2. 饥饿模式
mutex是golang提供的基础并发原语,可以帮助我们处理多goruntine并发访问共享资源的问题。每个goruntine都要再获取到锁之后才能操作共享资源,完成操作释放锁,保证了共享资源的读写安全性。 但这种方式也可能带来一些问题:一些悲惨的goruntine一直获取不到锁,导致业务逻辑不能继续完整执行,这种问题被称为"饥饿问题"
1. 正常模式
  1. 当前的mutex只有一个goruntine来获取,那么没有竞争,直接返回。
  2. 新的goruntine进来,如果当前mutex已经被获取了,则该goruntine进入一个先入先出的waiter队列,在mutex被释放后,waiter按照先进先出的方式获取锁。该goruntine会处于自旋状态(不挂起,继续占有cpu)。
  3. 新的goruntine进来,mutex处于空闲状态,将参与竞争。新来的 goroutine 有先天的优势,它们正在 CPU 中运行,可能它们的数量还不少,所以,在高并发情况下,被唤醒的 waiter 可能比较悲剧地获取不到锁,这时,它会被插入到队列的前面。如果 waiter 获取不到锁的时间超过阈值 1 毫秒,那么,这个 Mutex 就进入到了饥饿模式。
2. 饥饿模式
在饥饿模式下,Mutex 的拥有者将直接把锁交给队列最前面的 waiter。新来的 goroutine 不会尝试获取锁,即使看起来锁没有被持有,它也不会去抢,也不会 spin(自旋),它会乖乖地加入到等待队列的尾部。 如果拥有 Mutex 的 waiter 发现下面两种情况的其中之一,它就会把这个 Mutex 转换成正常模式:
  1. 此 waiter 已经是队列中的最后一个 waiter 了,没有其它的等待锁的 goroutine 了;
  2. 此 waiter 的等待时间小于 1 毫秒。
posted @ 2021-07-22 10:16  菜鸟的进击  阅读(561)  评论(0编辑  收藏  举报