写解锁会试图唤醒所有因欲进行的读锁定而堵塞的 goroutine
读解锁只会试图唤醒一个因欲进行写锁定而被堵塞的 goroutine
package main
import (
"fmt"
"sync"
"time"
)
// 读写锁
/**
sync.RWMutex 读写锁类型
提供的函数:
写锁:加锁/解锁
func (*RWMutex) Lock()
func (RWmutex) UnLock()
读锁:加锁/解锁
func (*RWMutex) RLock()
func (RWmutex) RUnLock()
写解锁会试图唤醒所有因欲进行的读锁定而堵塞的 goroutine
读解锁只会试图唤醒一个因欲进行写锁定而被堵塞的 goroutine
**/
func main() {
var rwm sync.RWMutex
for i := 0; i < 3; i++ {
go func(i int) {
fmt.Printf("准备开始读取。。。,尝试获取读锁定![%d]\n", i)
rwm.RLock()
fmt.Printf("获取到读锁定,开始读取。。。[%d]\n", i)
fmt.Printf("正在读取中,[%d]\n", i)
time.Sleep(time.Second * 2)
fmt.Printf("读取完成,开始释放读锁![%d]\n", i)
rwm.RUnlock()
fmt.Printf("读锁释放完成![%d]\n", i)
}(i)
}
time.Sleep(time.Microsecond * 1000)
fmt.Printf("主函数准备尝试获取写锁定![%s]\n", "main")
rwm.Lock()
fmt.Printf("主函数获取到写锁定![%s]\n", "main")
}
输出
准备开始读取。。。,尝试获取读锁定![1]
获取到读锁定,开始读取。。。[1]
正在读取中,[1]
准备开始读取。。。,尝试获取读锁定![0]
获取到读锁定,开始读取。。。[0]
正在读取中,[0]
准备开始读取。。。,尝试获取读锁定![2]
获取到读锁定,开始读取。。。[2]
正在读取中,[2]
主函数准备尝试获取写锁定![main]
读取完成,开始释放读锁![2]
读锁释放完成![2]
读取完成,开始释放读锁![0]
读锁释放完成![0]
读取完成,开始释放读锁![1]
读锁释放完成![1]
主函数获取到写锁定![main]
根据这个结果,可以看出:
- 读锁和写锁是互斥的!
- 读锁可以多个读锁并发读!
只有在所有的读锁释放后,写锁才能获取到!
另外一个指针函数
// 通过 sync.RWMutex 的指针函数获取锁本身(读锁)
var rwm sync.RWMutex
// 获取读写锁本身
locker := rwm.RLocker()
// 读加锁
locker.Lock()
// 读解锁
locker.Unlock()
这个 rwm.RLocker()
是实现了sync.Locker
接口类型,调用这个 rwm.RLocker()
函数后,实际上获取的是读写锁本身,但是所携带的locker.Lock()
和 locker.Unlock()
的操作却是指的读锁定和读解锁!也就是说这个操作只针对 读锁!
附上源码
func (rw *RWMutex) RLocker() Locker {
return (*rlocker)(rw)
}
type rlocker RWMutex
func (r *rlocker) Lock() { (*RWMutex)(r).RLock() }
func (r *rlocker) Unlock() { (*RWMutex)(r).RUnlock() }
Lock() 和 Unlock() 指的都是读加锁 和 读解锁 操作!
有疑问加站长微信联系(非本文作者)