ch9/ch9-03 #222
Replies: 1 comment
-
sync.RWMutex读写锁数据竞态是指在并发程序中,两个或更多的操作需要访问同一块内存,并且至少有一个操作是写入,而这些操作在不同的线程中进行,且不受同步机制保护。 要一种特殊类型的锁,其允许多个只读操作并行执行,但写操作会完全互斥。这种锁叫作“多读单写”锁(multiple readers, single writer lock),Go语言提供的这样的锁是sync.RWMutex。 本质上是读者写者模型的Go实现。 以下是加读者锁的源码: func (rw *RWMutex) RLock() {
if race.Enabled {
_ = rw.w.state
race.Disable()
}
if rw.readerCount.Add(1) < 0 {
// A writer is pending, wait for it.
runtime_SemacquireRWMutexR(&rw.readerSem, false, 0)
}
if race.Enabled {
race.Enable()
race.Acquire(unsafe.Pointer(&rw.readerSem))
}
} 这里 底层有许多原子操作(Load、CompareAndSwap等等)的实现,每个平台的实现略有差异。 这一部分的
然后在代码的最后, 而 type RWMutex struct {
w Mutex // held if there are pending writers
writerSem uint32 // semaphore for writers to wait for completing readers
readerSem uint32 // semaphore for readers to wait for completing writers
readerCount atomic.Int32 // number of pending readers
readerWait atomic.Int32 // number of departing readers
} 写者的锁则如下,除了竞态的判断,主要还是互斥获取写者锁、获取读者将至队列信号量(顺带把值降为0或0下)、等待当前读者结束(这一步还会把读者将之队列信号量的值转移到等待队列): // Lock locks rw for writing.
// If the lock is already locked for reading or writing,
// Lock blocks until the lock is available.
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 := rw.readerCount.Add(-rwmutexMaxReaders) + rwmutexMaxReaders
// Wait for active readers.
if r != 0 && rw.readerWait.Add(r) != 0 {
runtime_SemacquireRWMutex(&rw.writerSem, false, 0)
}
if race.Enabled {
race.Enable()
race.Acquire(unsafe.Pointer(&rw.readerSem))
race.Acquire(unsafe.Pointer(&rw.writerSem))
}
} 使用
|
Beta Was this translation helpful? Give feedback.
-
ch9/ch9-03
中文版
https://gopl-zh.github.io/ch9/ch9-03.html
Beta Was this translation helpful? Give feedback.
All reactions