RWMutex.Lock()在golang
问题描述:
在src/sync/rwmutex.go文件中的implementions,我们可以看到的 “锁定” 的定义如下:RWMutex.Lock()在golang
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
这句话手段。正如它所说,如何向读者公布?如何理解它?
答
你喜欢魔法吗?就是这样; o)不,我只是在开玩笑。
我们可以用
atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders)
从rw.readerCount这原子。减去rwmutexMaxReaders开始。新值存储在rw.readerCount中,并且也由函数返回。并且,当您添加rwmutexMaxReaders时,您只需在AddInt32之前计算旧值rw.readerCount。
答
在RWMutex上,调用Lock的作者可以防止更多读者获取RLock。这是为了防止作者的starvation。
假设以下情形:
假设读者已经获得了读取锁,然后
rw.readerCount
将1作家则试图获取写锁。在获得写入锁定(line 93)之后,它现在必须向所有读者发出信号,表明作者正在等待(所以他们不能继续)并等待所有读取器完成。该信号通过将
rw.readerCount
设置为负值(atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders)
)来设置。rw.readerCount
的值现在为1-rwmutexMaxReaders
。请注意,r
不是0,所以作者知道有一位读者仍在阅读。新读者现在想要获取读锁,它将012加入
rw.readerCount
(第48行),并检查它是否为负数。如果作者认为这是负面的,那么我们应该等待作家完成后再继续。
信号发生在rw.readerCount
的符号周围。
rw.readerCount Volker