3 回答

TA貢獻1735條經驗 獲得超5個贊
的確,您可以sync.RWMutex
在需要時使用sync.Mutex
.
我認為兩者都存在,因為在很多情況下 async.Mutex就足夠了(您不需要讀寫級別鎖定),并且實現sync.Mutex更簡單:需要更少的內存并且很可能更快。
sync.Mutex只有 8 個字節:
type Mutex struct {
? ? state int32
? ? sema? uint32
}
雖然sync.RWMutex是 8 + 16 = 24 字節(它包括一個sync.Mutex):
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 int32? // number of pending readers
? ? readerWait? int32? // number of departing readers
}
是的,您可以說 8 或 24 個字節無關緊要。只要您只有幾個互斥鎖,它就不會。
但是將互斥鎖放入它應該保護的結構中(嵌入或常規的命名字段)并不少見。現在,如果你有這些結構值的一部分,甚至可能有數千個,那么是的,它會產生明顯的不同。
此外,如果您只需要一個互斥量,sync.Mutex則可以減少濫用它的機會(您不會意外調用,RLock()因為它沒有該方法)。

TA貢獻1820條經驗 獲得超9個贊
提到的占用更多空間的一部分,它在執行時間方面的效率也較低。
如果我們查看 RWMutex.Lock 的源代碼:
// 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 := atomic.AddInt32(&rw.readerCount, -rwmutexMaxReaders) + rwmutexMaxReaders
// Wait for active readers.
if r != 0 && atomic.AddInt32(&rw.readerWait, r) != 0 {
runtime_SemacquireMutex(&rw.writerSem, false)
}
if race.Enabled {
race.Enable()
race.Acquire(unsafe.Pointer(&rw.readerSem))
race.Acquire(unsafe.Pointer(&rw.writerSem))
}
}
我們可以看到它調用了 Mutex.Lock,因此它花費了與 Mutex.Lock 相同的時間加上它所做的所有其他事情。
我們看到調用了atomic.AddInt32、runtime_SemacquireMutex等對象的方法race,這會有開銷。

TA貢獻1830條經驗 獲得超3個贊
sync.Mutex 的實現更簡單:需要更少的內存并且很可能更快。
檢查CL 329769(目前由Dmitry Vyukov進行的實驗)是否會進入 Go 1.18 將會很有趣:
考慮以下#golang RWMutex 算法調整
使編寫者與讀者和 Mutex 一樣快:
name old time/op new time/op delta
RWMutexWrite 22.3ns ± 0% 13.4ns ± 0% -40.23% (p=0.000 n=9+9)
RWMutexRead 13.4ns ± 0% 13.0ns ± 1% -2.40% (p=0.000 n=10+10)
RWMutexUncontended 42.1ns ± 0% 36.8ns ± 0% -12.69% (p=0.003 n=5+7)
- 3 回答
- 0 關注
- 186 瀏覽
添加回答
舉報