sync.RWMutex
是 Go 语言标准库中的读写互斥锁,适用于读多写少的并发场景。它允许同时有多个读取者(读者)访问共享资源,但只允许一个写入者(作者)独占访问。
下面是一个使用 sync.RWMutex
的示例:
Go
package main
import (
"fmt"
"sync"
)
type SharedData struct {
value int
rwMu sync.RWMutex
}
func (s *SharedData) Read() int {
s.rwMu.RLock() // 获取读锁
defer s.rwMu.RUnlock() // 无论是否发生 panic,确保释放读锁
return s.value
}
func (s *SharedData) Write(newValue int) {
s.rwMu.Lock() // 获取写锁
defer s.rwMu.Unlock() // 无论是否发生 panic,确保释放写锁
s.value = newValue
}
func main() {
shared := &SharedData{value: 0}
var wg sync.WaitGroup
wg.Add(3)
go func() {
defer wg.Done()
for i := 0; i < 5; i++ {
fmt.Printf("Reader: Value is %d\n", shared.Read())
}
}()
go func() {
defer wg.Done()
for i := 0; i < 5; i++ {
shared.Write(i)
fmt.Printf("Writer: Set value to %d\n", i)
}
}()
go func() {
defer wg.Done()
for i := 0; i < 5; i++ {
fmt.Printf("Reader: Value is %d\n", shared.Read())
}
}()
wg.Wait()
}
在这个示例中:
- 定义了一个
SharedData
结构体,包含一个整数值value
和一个sync.RWMutex
类型的字段rwMu
,用于保护对value
的并发访问。 - 为
SharedData
结构体定义了两个方法:Read()
方法:获取读锁(RLock()
),读取value
并返回,然后释放读锁(RUnlock()
)。Write()
方法:获取写锁(Lock()
),更新value
,然后释放写锁(Unlock()
)。 - 主函数中创建了一个
SharedData
实例shared
。 - 启动三个并发任务(goroutines):第一个和第三个任务作为读者,不断读取
shared
的值并打印。第二个任务作为写者,循环设置shared
的值,并打印已设置的值。 - 使用
sync.WaitGroup
确保所有 goroutines 执行完毕后,主程序才退出。
这个示例展示了如何使用 sync.RWMutex
来保护共享数据的并发读写。读取者(Read()
方法)使用读锁,允许多个读取者同时访问;写入者(Write()
方法)使用写锁,确保在写入期间没有其他读取者或写入者干扰。这样既能保证数据一致性,又能提高读取密集型场景下的并发性能。