Sobes.tech
Middle+

Kaip apsaugoti save nuo klaidų konkurencijos rašymo metu žemėlapyje?

sobes.tech AI

Atsakymas iš AI

Siekiant apsaugoti nuo klaidų konkurencinio įrašo map Golang'e, kuris pagal numatytuosius nustatymus nėra srautinio saugumo, naudojami šie mechanizmai:

  • sync.Mutex: Užrakinti map prieš įrašą ir atrakinti po įrašo.

    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: Leidžia kelioms gorutinoms vienu metu skaityti iš map, bet blokuoja įrašą, kai vyksta skaitymas ar įrašymas.

    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() // Rašymo užraktas
        defer sm.mu.Unlock()
        sm.data[key] = value
    }
    
    func (sm *SafeMapRWMutex) Get(key string) (int, bool) {
        sm.mu.RLock() // Skaitymo užraktas
        defer sm.mu.RUnlock()
        val, ok := sm.data[key]
        return val, ok
    }
    
  • sync.Map: Specializuotas, srautinio saugumo tipas, optimizuotas scenarijams, kur raktų rinkinys yra santykinai stabilus, įrašai yra reti arba kai keli gorutinai skaito ir rašo skirtingus raktų rinkinius.

    import "sync"
    
    var safeMap sync.Map // Deklaracija
    
    func UseSyncMap() {
        safeMap.Store("key1", 10) // Rašymas
        if val, ok := safeMap.Load("key1"); ok { // Skaitymas
            // Naudokite val
        }
        safeMap.Delete("key1") // Ištrynimas
    }
    

Palyginimas:

Mechanizmas Privalumai Trūkumai Taikymas
sync.Mutex Paprastas naudoti Blokuoja visas operacijas rašymo metu Paprasti scenarijai, kur konkurencija nėra aukšta arba skaitymas/rašymas yra beveik vienodi.
sync.RWMutex Leidžia paralelį skaitymą Sudėtingesnis nei sync.Mutex. Rašymas blokuoja skaitymą ir kitus rašymus. Scenarijai su dažnu skaitymu ir retu rašymu.
sync.Map Optimizuotas tam tikriems scenarijams Turėa ribotą API. Gali būti lėtesnis nei Mutex, jei prieiga yra visiškai atsitiktinė. Scenarijai su santykinai stabiliu raktų rinkiniu arba disjunktiniais raktų rinkiniais, prieinamais skirtingoms gorutinoms.

Pasirinkimas priklauso nuo konkurencinio prieigos pobūdžio prie mapo. Bendru atveju dažnai pakanka sync.Mutex arba sync.RWMutex. Specialiems scenarijams sync.Map gali užtikrinti geresnį našumą.