Sobes.tech
Middle+

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.