Jakie mutexy używasz, aby zapewnić bezpieczeństwo podczas pracy z mapami w Go?
sobes.tech AI
Odpowiedź od AI
Aby zapewnić bezpieczeństwo podczas pracy z niekonkurencyjnym dostępem do struktur danych, w tym map (map), w Go używa się mutexów z pakietu sync.
sync.Mutex: Podstawowy mutex do wyłącznej blokady. Używany do blokowania i odblokowywania sekcji kodu, w których odczyt lub zapis odbywa się na mapie.sync.RWMutex: Mutex z dostępem współdzielonym (czytanie) i wyłącznym (zapis). Pozwala wielu gorutynom czytać z mapy jednocześnie, ale tylko jednej zapisywać. Idealny w scenariuszach, gdzie odczytów jest znacznie więcej niż zapisów.
Preferowanym rozwiązaniem do współbieżnej i bezpiecznej pracy z mapami jest sync.RWMutex, ponieważ zapewnia lepszą wydajność przy wielu równoczesnych operacjach odczytu.
Przykład użycia sync.RWMutex:
import (
"sync"
)
type SafeMap struct {
mu sync.RWMutex
m map[string]int
}
func NewSafeMap() *SafeMap {
return &SafeMap{
m: make(map[string]int),
}
}
func (sm *SafeMap) Set(key string, value int) {
sm.mu.Lock() // Blokada do zapisu
defer sm.mu.Unlock()
sm.m[key] = value
}
func (sm *SafeMap) Get(key string) (int, bool) {
sm.mu.RLock() // Blokada do odczytu
defer sm.mu.RUnlock()
value, ok := sm.m[key]
return value, ok
}
Istnieje również specjalistyczny typ sync.Map, który jest zoptymalizowany do użycia w środowiskach współbieżnych bez jawnego blokowania mutexami w większości przypadków, ale ma pewne ograniczenia i inną API. Jednakże, jeśli potrzebna jest bardziej elastyczna kontrola nad blokadami lub specyficzne scenariusze dostępu, użycie sync.RWMutex na standardowej mapie jest powszechną praktyką.