Стандартная библиотека Go предоставляет два основных типа мьютексов в пакете sync:
Характеристики:
Пример использования:
var mu sync.Mutex
var counter int
func increment() {
mu.Lock()
defer mu.Unlock()
counter++
}
Особенности:
Lock() горутина блокируется, пока мьютекс не будет доступенUnlock() должен вызываться той же горутиной, что и Lock()Характеристики:
RLock()/RUnlock() - для читателейLock()/Unlock() - для писателейПример использования:
var rwmu sync.RWMutex
var data map[string]string
func readValue(key string) string {
rwmu.RLock()
defer rwmu.RUnlock()
return data[key]
}
func writeValue(key, value string) {
rwmu.Lock()
defer rwmu.Unlock()
data[key] = value
}
Преимущества RWMutex:
| Характеристика | sync.Mutex | sync.RWMutex |
|---|---|---|
| Блокировка чтения | Полная | Множественная |
| Блокировка записи | Полная | Эксклюзивная |
| Производительность | Базовая | Выше для read-heavy |
| Сложность | Проще | Сложнее |
var mu sync.Mutex
func fatal() {
mu.Lock()
mu.Lock() // Deadlock - вторая блокировка в той же горутине
}
стандартная библиотека Go предоставляет два типа мьютексов - обычный sync.Mutex для эксклюзивного доступа и sync.RWMutex для оптимизированного read-heavy доступа. Выбор между ними зависит от паттерна доступа к защищаемым данным.