Sobes.tech
Middle+

Ako sa chrániť pred chybami pri súbežnom zápise do mapy?

sobes.tech AI

Odpoveď od AI

Na ochranu pred chybami pri konkurenom zápise do map v Golangu, ktoré nie sú predvolene bezpečné pre vlákna, sa používajú nasledujúce mechanizmy:

  • sync.Mutex: Zámok mapy pred zápisom a odomknutie po zápise.

    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 súčasné čítanie z mapy viacerými gorutinami, ale blokuje zápis počas súčasného čítania alebo 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ámok pre zápis
        defer sm.mu.Unlock()
        sm.data[key] = value
    }
    
    func (sm *SafeMapRWMutex) Get(key string) (int, bool) {
        sm.mu.RLock() // Zámok pre čítanie
        defer sm.mu.RUnlock()
        val, ok := sm.data[key]
        return val, ok
    }
    
  • sync.Map: Špecializovaný typ, bezpečný pre vlákna, optimalizovaný pre scenáre, kde je sada kľúčov relatívne stabilná, zápisy sú zriedkavé, alebo keď viac gorutín číta a zapisuje pre disjunktívne sady kľúčov.

    import "sync"
    
    var safeMap sync.Map // Deklarácia
    
    func UseSyncMap() {
        safeMap.Store("key1", 10) // Zápis
        if val, ok := safeMap.Load("key1"); ok { // Čítanie
            // Použite val
        }
        safeMap.Delete("key1") // Vymazanie
    }
    

Porovnanie prístupov:

Mechanizmus Výhody Nevýhody Použitie
sync.Mutex Jednoduché použitie Blokuje všetky operácie pri zápise Jednoduché scenáre, kde konkurencia nie je vysoká alebo čítanie/zápis sú približne rovnaké.
sync.RWMutex Umožňuje paralelné čítanie Zložitejšie ako sync.Mutex. Zápis blokuje čítanie a iné zápisy. Scenáre s častým čítaním a zriedkavým zápisom.
sync.Map Optimalizované pre určité scenáre Obmedzené API. Môže byť pomalšie ako Mutex, ak prístup je úplne náhodný. Scenáre s relatívne stabilnými kľúčmi alebo disjunktnými sadami kľúčov pre prístup rôznych gorutín.

Výber konkrétneho prístupu závisí od charakteru konkurenčného prístupu k mapu. Pre všeobecné prípady je často postačujúci sync.Mutex alebo sync.RWMutex. Pre špecifické scenáre môže sync.Map zabezpečiť lepší výkon.