Source Code
A RWMutex is a reader/writer mutual exclusion lock. The lock can be held by an arbitrary number of readers or a single writer. The zero value for a RWMutex is an unlocked mutex.
A RWMutex must not be copied after first use.
If a goroutine holds a RWMutex for reading and another goroutine might call Lock, no goroutine should expect to be able to acquire a read lock until the initial read lock is released. In particular, this prohibits recursive read locking. This is to ensure that the lock eventually becomes available; a blocked Lock call excludes new readers from acquiring the lock.
type RWMutex struct {
w Mutex // held if there are pending writers
writerSem uint32 // semaphore for writers to wait for completing readers
// 这个 semaphore 在作用是:当ongoing reader 完成了,waiting writer可以被通知到,并且解除blocked,以进行writing
// 调用 runtime_Semrelease(&rw.writerSem) 可以unblock blocked writer (by wakeup it via semaphore),这时候调用了 runtime_SemacquireMutex(&rw.writerSem) 的地方就不会继续被blocked了
// 调用 runtime_SemacquireMutex(&rw.writerSem) 的地方会被 blocked,直到 runtime_Semrelease(&rw.writerSem) 被调用
readerSem uint32 // semaphore for readers to wait for completing writers
// 这个 semaphore 在作用是:当ongoing writing 完成了,waiting reader可以被通知到,并且解除blocked,以进行reading
// 调用 runtime_Semrelease(&rw.readerSem) 可以 Unblock blocked readers (by wakeup them via semaphore),这时候调用了 runtime_SemacquireMutex(&rw.readerSem) 的地方就不会继续被blocked了
// 调用 runtime_SemacquireMutex(&rw.readerSem) 的地方会被 block,直到 runtime_Semrelease(&rw.readerSem) 被调用
readerCount int32 // number of pending readers
// if readerCount < 0, means a writing is ongoing (thus all readers have to wait, until the writing is done)
// if readerCount == 0, means no ongoing writing and no onging reading
// if readerCount > 0, mean has onging reading, but no ongoing writing
readerWait int32 // number of departing readers
}
这意味着:
- 当有writer进来时,
- 如果这时候没有ongoing reader,writer就直接write
- 如果这时候有ongoing reader,writer就一直等待(被阻塞在
runtime_SemacquireMutex(&rw.writerSem),直到
- 当有reader进来时,
- 如果这时候没有ongoing writer,reader就直接read
- 如果这时候有ongoing writer,reader一直等待(被阻塞在
untime_SemacquireMutex(&rw.readerSem)),直到writer完成(writer完成后,会调用runtime_Semrelease(&rw.readerSem)来通知所有reader)
...