《Go题库·16》读写锁底层是怎么实现的

本文探讨了Go语言中的读写锁RWMutex,它解决了在读操作频繁时性能下降的问题,通过对比Mutex展示了RWMutex如何允许并发读取,提高效率。读写锁分为Read-perferring、Write-prferring和不指定优先级三种模型,Go的RWMutex采用Write-prferring策略,防止写饥饿。同时,文章介绍了读写锁的四条规则和内部的互斥锁机制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目解析 GOLANG ROADMAP社区

答案(自由)

读写锁的底层是基于互斥锁实现的。

  • 为什么有读写锁,它解决了什么问题?(使用场景)
  • 它的底层原理是什么?

在这里我会结合 Go 中的读写锁 RWMutex 进行介绍。

我们通过与 Mutex 对比得出答案。Mutex 是不区分 goroutine 对共享资源的操作行为的,在读操作、它会上锁,在写操作,它也会上锁,当一段时间内,读操作居多时,读操作在 Mutex 的保护下也不得不变为串行访问,对性能的影响也就比较大了。

RWMutex 读写锁的诞生为了区分读写操作,在进行读操作时,goroutine 就不必傻傻的等待了,而是可以并发地访问共享资源,将串行读变成了并行读,提高了读操作的性能。

读写锁针对解决一类问题:readers-writes ,同时有多个读或者多个写操作时,只要有一个线程在执行写操作,其他的线程都不能进行读操作。

读写锁其实有三种工作模型:

  • Read-perferring
优先读设计,可能会导致写饥饿
  • Write-prferring
优先写设计,避免写饥饿
  • 不指定优先级
不区分优先级,解决饥饿问题

Go 中的读写锁,工作模型是 Write-prferring 方案。

答案(栾龙生)

  1. 读写锁解决问题

    主要应用于写操作少,读操作多的场景。读写锁满足以下四条规则。

    • 写锁需要阻塞写锁:一个协程拥有写锁时,其他协程写锁定需要阻塞;
    • 写锁需要阻塞读锁:一个协程拥有写锁时,其他协程读锁定需要阻塞;
    • 读锁需要阻塞写锁:一个协程拥有读锁时,其他协程写锁定需要阻塞;
    • 读锁不能阻塞读锁:一个协程拥有读锁时,其他协程也可以拥有读锁。
  2. 读写锁底层实现

    读写锁内部仍有一个互斥锁,用于将多个写操作隔离开来,其他几个都用于隔离读操作和写操作。

    源码包src/sync/rmmutex.go:RWMutex中定义了读写锁的数据结构

type RWMutex struct {
    w           Mutex  // held if there are pending writers
    writerSem   uint32 // semaphore for writers to wait for completing readers
    readerSem   uint32 // semaphore for readers to wait for completing writers
    readerCount int32  // number of pending readers
    readerWait  int32  // number of departing readers
}

本文由 GOLANG ROADMAP 发布!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值