type RWMutex struct {
w Mutex // held if there are pending writers
writerSem uint32 // 写的信号量
readerSem uint32 // 读的信号量
readerCount int32 // 等待写的个数
readerWait int32 // 等待读的个数
}
// 加“读锁”
// 对readerCount + 1 。
// 然后看 readerCount是不是小于0
// 小于0表示 正在加写锁,然后阻塞到rw.readerSem 这个信号上。
func (rw *RWMutex) RLock() {
if atomic.AddInt32(&rw.readerCount, 1) < 0 {
// A writer is pending, wait for it.
runtime_SemacquireMutex(&rw.readerSem, false, 0)
}
}
// 释放 “读锁”
// 对readerCount - 1 。
// 然后看 readerCount是不是小于0
// 小于0表示 正在加写锁,然后调用rw.rUnlockSlow
func (rw *RWMutex) RUnlock() {
if r := atomic.AddInt32(&rw.readerCount, -1); r < 0 {
// Outlined slow-path to allow the fast-path to be inlined
rw.rUnlockSlow(r)
}
}
// r+1 == -rwmutexMaxReaders 表示“读锁”已经释放,抛出异常
// rw.readerWait - 1
// rw.readerWait - 1 = 0 表示所有读锁都释放了
// 所有读锁都释放了可以唤醒 rw.writerSem 对应 写锁的lock方法继续执行
func (rw *RWMutex) rUnlockSlow(r int32) {
if r+1 == 0 || r+1 == -rwmutexMaxReaders {
race.Enable()
throw("sync: RUnlock of unlocked RWMutex")
}
// A writer is pending.
if atomic.AddInt32(&rw.readerWait, -1) == 0 {
// The last reader unblocks the writer.
runtime_Semrelease(&rw.writerSem, false, 1)
}
}
// mutex 加锁,保证写锁和写锁之间互斥
// rw.readerCount - rwmutexMaxReaders
// r 表示读锁数量
// rw.readerWait + 读lock的数量
// 等待 rw.writerSem 的信号 (读锁那边释放完了,会发这个信号)
func (rw *RWMutex) Lock() {
// First, resolve competition with other writers.
rw.w.Lock()
// Announce to readers there is a pending writer.
r := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders
// Wait for active readers.
if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {
runtime_SemacquireMutex(&rw.writerSem, false, 0)
}
}
// rw.readerCount + rwmutexMaxReaders
// r 表示读锁的数量,大于 rwmutexMaxReaders 就抛出异常
// 发送 rw.readerSem 信号量,通知RLock 代码可以继续执行。
func (rw *RWMutex) Unlock() {
// Announce to readers there is no active writer.
r := atomic.AddInt32(&rw.readerCount, rwmutexMaxReaders)
if r >= rwmutexMaxReaders {
race.Enable()
throw("sync: Unlock of unlocked RWMutex")
}
// Unblock blocked readers, if any.
for i := 0; i < int(r); i++ {
runtime_Semrelease(&rw.readerSem, false, 0)
}
网友评论