79 lines
1.0 KiB
Go
79 lines
1.0 KiB
Go
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()
|
|
}
|