面试题答案
一键面试读写锁原理
sync.RWMutex
是Go语言标准库提供的读写锁。其原理基于读操作可以并发执行,而写操作必须独占资源。读写锁有两种模式:读模式和写模式。
- 读模式:多个读操作可以同时进行,因为读操作不会修改共享资源,所以不会产生数据竞争。
- 写模式:写操作必须是独占的,当一个写操作在进行时,不允许其他读操作或写操作进行,以确保数据的一致性。
使用方式
以下是一个简单的示例代码,展示如何在Go中使用 sync.RWMutex
:
package main
import (
"fmt"
"sync"
)
var (
data int
rwmu sync.RWMutex
)
func read(wg *sync.WaitGroup) {
defer wg.Done()
rwmu.RLock()
fmt.Printf("Read data: %d\n", data)
rwmu.RUnlock()
}
func write(wg *sync.WaitGroup, value int) {
defer wg.Done()
rwmu.Lock()
data = value
fmt.Printf("Write data: %d\n", data)
rwmu.Unlock()
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go read(&wg)
}
for i := 0; i < 2; i++ {
wg.Add(1)
go write(&wg, i*10)
}
wg.Wait()
}
在上述代码中:
read
函数使用rwmu.RLock()
来获取读锁,允许多个读操作并发执行。操作完成后使用rwmu.RUnlock()
释放读锁。write
函数使用rwmu.Lock()
来获取写锁,写操作完成后使用rwmu.Unlock()
释放写锁。写锁是独占的,获取写锁时不允许其他读写操作。
与普通互斥锁相比的优势
- 性能提升:在读写比例悬殊(读多写少)的场景下,读写锁允许并发读操作,大大提高了程序的并发性能。而普通互斥锁(
sync.Mutex
)无论读写都只允许一个操作进行,读操作也会被阻塞,导致性能瓶颈。 - 资源利用率:读写锁能更好地利用系统资源,因为读操作不需要等待其他读操作完成,可以同时进行。而普通互斥锁会使读操作串行化,降低了资源利用率。