Ответ
RWMutex
(мьютекс чтения-записи) стоит использовать в сценариях, где количество операций чтения значительно превышает количество операций записи. Это называется "read-heavy" нагрузкой.
Основной принцип работы:
RLock()
(блокировка на чтение) может быть захвачена множеством горутин одновременно. Пока есть хотя бы один читатель, никто не может получить блокировку на запись.Lock()
(блокировка на запись) является эксклюзивной. Когда горутина захватываетLock()
, ни одна другая горутина не может получить ниRLock()
, ниLock()
.
Это позволяет множеству читателей безопасно работать с данными параллельно, что значительно повышает производительность.
Пример: кэш в памяти
var (
cache = make(map[string]string)
rw sync.RWMutex
)
// Множество горутин могут вызывать Get одновременно
func Get(key string) string {
rw.RLock() // Блокировка на чтение
defer rw.RUnlock()
return cache[key]
}
// Только одна горутина может вызывать Set в один момент времени
func Set(key, value string) {
rw.Lock() // Эксклюзивная блокировка на запись
defer rw.Unlock()
cache[key] = value
}
Когда использовать Mutex
?
- Когда операции чтения и записи сбалансированы или преобладает запись.
- Когда критическая секция (код под блокировкой) очень короткая.
RWMutex
имеет более высокие накладные расходы, и на очень быстрых операцияхMutex
может оказаться производительнее. - Когда логика проста и не требует разделения блокировок.
Mutex
проще в использовании и анализе.