coding-lab/sync/rwmutex_v1.go

79 lines
1.0 KiB
Go
Raw Normal View History

2023-09-18 17:38:04 +08:00
package sync
import (
"sync"
)
/*
ChannelRWMutexV1
使用四把锁
*/
type ChannelRWMutexV1 struct {
mu sync.Mutex // 互斥锁
rm sync.Mutex // 读等待锁
wm sync.Mutex // 写等待锁
cmu sync.Mutex // 计数锁
rn int // 读等待
wn int // 写等待
}
func NewRWMutexV1() RWLocker {
return &ChannelRWMutexV1{}
}
func (rw *ChannelRWMutexV1) RLock() {
rw.cmu.Lock()
if rw.wn > 0 {
rw.cmu.Unlock()
rw.wm.Lock()
rw.wm.Unlock()
} else {
defer rw.cmu.Unlock()
}
rw.rn++
if rw.rn == 1 {
rw.wm.Lock()
}
}
func (rw *ChannelRWMutexV1) RUnlock() {
rw.cmu.Lock()
defer rw.cmu.Unlock()
rw.rn--
if rw.rn == 0 {
rw.wm.Unlock()
}
}
func (rw *ChannelRWMutexV1) Lock() {
rw.cmu.Lock()
if rw.rn > 0 {
rw.cmu.Unlock()
rw.wm.Lock()
rw.wm.Unlock()
} else {
defer rw.cmu.Unlock()
}
rw.wn++
if rw.wn == 1 {
rw.rm.Lock()
}
rw.mu.Lock()
}
func (rw *ChannelRWMutexV1) Unlock() {
rw.cmu.Lock()
defer rw.cmu.Unlock()
rw.wn--
if rw.wn == 0 {
rw.rm.Unlock()
}
rw.mu.Unlock()
}