Jak se chránit před chybami při konkurenčním zápisu do mapy?
sobes.tech AI
Odpověď od AI
Pro ochranu před chybami při konkurenčním zápisu do map v Golangu, které nejsou ve výchozím nastavení vlákny bezpečné, se používají následující mechanismy:
-
sync.Mutex: Zamčení mapy před zápisem a odemčení po zápisu.import "sync" type SafeMap struct { mu sync.Mutex data map[string]int } func NewSafeMap() *SafeMap { return &SafeMap{ data: make(map[string]int), } } func (sm *SafeMap) Set(key string, value int) { sm.mu.Lock() defer sm.mu.Unlock() sm.data[key] = value } func (sm *SafeMap) Get(key string) (int, bool) { sm.mu.Lock() defer sm.mu.Unlock() val, ok := sm.data[key] return val, ok } -
sync.RWMutex: Umožňuje současné čtení z mapy více gorutinami, ale blokuje zápis při současném čtení nebo zápisu.import "sync" type SafeMapRWMutex struct { mu sync.RWMutex data map[string]int } func NewSafeMapRWMutex() *SafeMapRWMutex { return &SafeMapRWMutex{ data: make(map[string]int), } } func (sm *SafeMapRWMutex) Set(key string, value int) { sm.mu.Lock() // Zámek pro zápis defer sm.mu.Unlock() sm.data[key] = value } func (sm *SafeMapRWMutex) Get(key string) (int, bool) { sm.mu.RLock() // Zámek pro čtení defer sm.mu.RUnlock() val, ok := sm.data[key] return val, ok } -
sync.Map: Specializovaný typ bezpečný pro vlákna, optimalizovaný pro scénáře, kde je sada klíčů relativně stabilní, zápisy jsou vzácné, nebo když několik gorutin čte a zapisuje pro disjunktní sady klíčů.import "sync" var safeMap sync.Map // Deklarace func UseSyncMap() { safeMap.Store("key1", 10) // Zápis if val, ok := safeMap.Load("key1"); ok { // Čtení // Použijte val } safeMap.Delete("key1") // Vymazání }
Porovnání přístupů:
| Mechanismus | Výhody | Nevýhody | Použití |
|---|---|---|---|
sync.Mutex |
Jednoduché použití | Blokuje všechny operace při zápisu | Jednoduché scénáře, kde není vysoká konkurence nebo je čtení/zápis přibližně stejné. |
sync.RWMutex |
Umožňuje paralelní čtení | Složitější než sync.Mutex. Zápis blokuje čtení i zápisy. |
Scénáře s častým čtením a vzácným zápisem. |
sync.Map |
Optimalizované pro určité scénáře | Omezené API. Může být pomalejší než Mutex, pokud je přístup zcela náhodný. |
Scénáře s relativně stabilními klíči nebo disjunktními sadami klíčů pro přístup různých gorutin. |
Výběr konkrétního přístupu závisí na charakteru konkurenčního přístupu k mapě. Pro obecné případy je často dostačující sync.Mutex nebo sync.RWMutex. Pro specifické scénáře může sync.Map poskytnout lepší výkon.