Sobes.tech
Middle+

Hoe bescherm je jezelf tegen fouten bij gelijktijdig schrijven in een map?

sobes.tech AI

Antwoord van AI

Om fouten te voorkomen bij gelijktijdige schrijfbewerkingen in map in Golang, die standaard niet thread-safe zijn, worden de volgende mechanismen gebruikt:

  • sync.Mutex: Blokkeert de map voor het schrijven en ontgrendelt deze daarna.

    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: Staat gelijktijdig lezen uit de map toe door meerdere goroutines, maar blokkeert schrijven tijdens gelijktijdig lezen of schrijven.

    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() // Schrijfslot
        defer sm.mu.Unlock()
        sm.data[key] = value
    }
    
    func (sm *SafeMapRWMutex) Get(key string) (int, bool) {
        sm.mu.RLock() // Leeslot
        defer sm.mu.RUnlock()
        val, ok := sm.data[key]
        return val, ok
    }
    
  • sync.Map: Gespecialiseerd thread-safe type, geoptimaliseerd voor scenario's waarin de set van sleutels relatief stabiel is en schrijfbewerkingen zeldzaam zijn, of wanneer meerdere goroutines lezen en schrijven voor disjuncte sets van sleutels.

    import "sync"
    
    var safeMap sync.Map // Declaratie
    
    func UseSyncMap() {
        safeMap.Store("key1", 10) // Schrijven
        if val, ok := safeMap.Load("key1"); ok { // Lezen
            // Gebruik val
        }
        safeMap.Delete("key1") // Verwijderen
    }
    

Vergelijking van benaderingen:

Mechanisme Voordelen Nadelen Toepassing
sync.Mutex Eenvoudig te gebruiken Blokkeert alle operaties tijdens schrijven Eenvoudige scenario's, waar gelijktijdigheid niet hoog is of lezen/schrijven vergelijkbaar zijn.
sync.RWMutex Staat gelijktijdig lezen toe Complexer dan sync.Mutex. Schrijven blokkeert lezen en andere schrijfbewerkingen. Scenario's met veel lezen en weinig schrijven.
sync.Map Geoptimaliseerd voor bepaalde scenario's Heeft een beperkte API. Kan trager zijn dan Mutex bij volledig willekeurige toegang. Scenario's met relatief stabiele sleutels of disjuncte sets van sleutels voor verschillende goroutines.

De keuze voor een specifieke aanpak hangt af van de aard van de gelijktijdige toegang tot de map. Voor algemene gevallen zijn sync.Mutex of sync.RWMutex vaak voldoende. Voor specifieke scenario's kan sync.Map betere prestaties bieden.