面试题答案
一键面试读写锁工作原理
- 读锁(RLock):当一个Goroutine获取读锁时,其他Goroutine也可以同时获取读锁。这是因为读操作不会修改共享数据,多个读操作同时进行不会产生数据不一致问题。
- 写锁(Lock):当一个Goroutine获取写锁时,其他Goroutine无论是读锁还是写锁都无法获取,直到写锁被释放。这是为了保证在写操作时,共享数据不会被其他读写操作干扰,确保数据一致性。
代码示例
package main
import (
"fmt"
"sync"
)
var (
data int
rwmu sync.RWMutex
wg sync.WaitGroup
)
func reader(id int) {
defer wg.Done()
rwmu.RLock()
defer rwmu.RUnlock()
fmt.Printf("Reader %d reads data: %d\n", id, data)
}
func writer(id int) {
defer wg.Done()
rwmu.Lock()
defer rwmu.Unlock()
data = id
fmt.Printf("Writer %d writes data: %d\n", id, data)
}
func main() {
for i := 0; i < 3; i++ {
wg.Add(1)
go writer(i)
}
for i := 0; i < 5; i++ {
wg.Add(1)
go reader(i)
}
wg.Wait()
}
在上述代码中:
data
是共享数据。rwmu
是读写锁实例。reader
函数使用rwmu.RLock()
获取读锁,多个reader
可以同时运行。writer
函数使用rwmu.Lock()
获取写锁,在写操作时会阻止其他读写操作。main
函数中启动多个读写Goroutine,sync.WaitGroup
用于等待所有Goroutine完成。