go mutex的模式

编辑于 2022-10-25 16:19:02 阅读 1220

mutex 有正常模式饥饿模式

mutex是golang提供的基础并发原语,可以帮助我们处理多goruntine并发访问共享资源的问题。每个goruntine都要再获取到锁之后才能操作共享资源,完成操作释放锁,保证了共享资源的读写安全性。 但这种方式也可能带来一些问题:一些悲惨的goruntine一直获取不到锁,导致业务逻辑不能继续完整执行,这种问题被称为"饥饿问题"

正常模式

  • 当前的mutex只有一个goruntine来获取,那么没有竞争,直接返回。
  • 新的goruntine进来,如果当前mutex已经被获取了,则该goruntine进入一个先入先出的waiter队列,在mutex被释放后,waiter按照先进先出的方式获取锁。该goruntine会处于自旋状态(不挂起,继续占有cpu)。
  • 新的goruntine进来,mutex处于空闲状态,将参与竞争。新来的 goroutine 有先天的优势,它们正在 CPU 中运行,可能它们的数量还不少,所以,在高并发情况下,被唤醒的 waiter 可能比较悲剧地获取不到锁,这时,它会被插入到队列的前面。如果 waiter 获取不到锁的时间超过阈值 1 毫秒,那么,这个 Mutex 就进入到了饥饿模式。

饥饿模式

在饥饿模式下,Mutex 的拥有者将直接把锁交给队列最前面的 waiter。新来的 goroutine 不会尝试获取锁,即使看起来锁没有被持有,它也不会去抢,也不会 spin(自旋),它会乖乖地加入到等待队列的尾部。 如果拥有 Mutex 的 waiter 发现下面两种情况的其中之一,它就会把这个 Mutex 转换成正常模式:

  • 此 waiter 已经是队列中的最后一个 waiter 了,没有其它的等待锁的 goroutine 了;
  • 此 waiter 的等待时间小于 1 毫秒。

来源

https://www.cnblogs.com/tsxylhs/p/15042871.html

广而告之,我的新作品《语音助手》上架Google Play了,欢迎下载体验