在src/sync/rwmutex.go文件中,我们可以看到" Lock"的定义如下:
func (rw *RWMutex) Lock() {
if race.Enabled {
_ = rw.w.state
race.Disable()
}
// 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_Semacquire(&rw.writerSem)
}
if race.Enabled {
race.Enable()
race.Acquire(unsafe.Pointer(&rw.readerSem))
race.Acquire(unsafe.Pointer(&rw.writerSem))
}
}
所以我真的很想知道
atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders
这句话的意思。正如它所说,如何向读者宣布?如何理解?
答案 0 :(得分:0)
我们可以从
开始atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders)
这个来自rw.readerCount的原子减去rwmutexMaxReaders。新值存储在rw.readerCount中,也由函数返回。当您添加rwmutexMaxReaders时,您只需在AddInt32之前计算旧值rw.readerCount。
答案 1 :(得分:0)
在RWMutex上,一个调用Lock的编写器阻止更多读者获取RLock。这样做是为了防止starvation作者。
假设以下情形:
假设读者已获得读锁定,则rw.readerCount
将为1.
然后,编写器尝试获取写锁定。在获得写锁定(line 93)之后,它现在必须向所有读者发出信号,表示作者正在等待(因此他们无法继续)并等待所有读者完成。通过将rw.readerCount
设置为负值({{1}})来设置信号。 atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders)
的值现在为rw.readerCount
。请注意1-rwmutexMaxReaders
不是0,因此作者知道有一个读者仍在阅读。
新的Reader现在想要获取读锁定,它会向r
添加1(第48行)并检查它是否为负数。如果它是否定的,作者已将其设置为这样,我们应该等待作者完成然后再继续。
信号发生在rw.readerCount
的标志周围。