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()
|
||
|
}
|