Sobes.tech
Middle+

Kuidas kaitsta end konkurentsa kirjutamise ajal kaardil vigu?

sobes.tech AI

Vastus AI-lt

Kaitseks, et kaitseks konkurējošā ierakstā map Golang, kas pēc noklusējuma nav šķidruma drošs, tiek izmantoti šādi mehānismi:

  • sync.Mutex: Bloķē map pirms ieraksta un atbloķē pēc tam.

    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: Atļauj vienlaikus lasīt no map vairākām gorutinām, bet bloķē ierakstu konkurējošā lasīšanā vai rakstīšanā.

    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() // Rakstīšanas bloķēšana
        defer sm.mu.Unlock()
        sm.data[key] = value
    }
    
    func (sm *SafeMapRWMutex) Get(key string) (int, bool) {
        sm.mu.RLock() // Lasīšanas bloķēšana
        defer sm.mu.RUnlock()
        val, ok := sm.data[key]
        return val, ok
    }
    
  • sync.Map: Specializēts šķidruma drošs tips, optimizēts scenārijiem, kuros atslēgu kopums ir relatīvi stabils, ieraksti ir reti, vai arī vairākas gorutinas lasa un raksta disjunktos atslēgu kopumos.

    import "sync"
    
    var safeMap sync.Map // Deklarācija
    
    func UseSyncMap() {
        safeMap.Store("key1", 10) // Ieraksts
        if val, ok := safeMap.Load("key1"); ok { // Lasīšana
            // Izmanto val
        }
        safeMap.Delete("key1") // Dzēšana
    }
    

Salīdzinājums pieejām:

Mehānisms Priekšrocības Trūkumi Pielietojums
sync.Mutex Vienkārši lietojams Bloķē visas operācijas ieraksta laikā Vienkārši scenāriji, kur konkurētspēja ir zema vai lasīšana/rakstīšana ir līdzīga.
sync.RWMutex Atļauj paralēlu lasīšanu Sarežģītāks nekā sync.Mutex. Ieraksts bloķē lasīšanu un citus ierakstus. Scenāriji ar biežu lasīšanu un retu rakstīšanu.
sync.Map Optimizēts noteiktiem scenārijiem Ierobežots API. Var būt lēnāks par Mutex, ja piekļuve ir pilnībā nejauša. Scenāriji ar relatīvi stabilām atslēgām vai disjunktiem atslēgu kopumiem dažādām gorutīnām.

Konkrētas pieejas izvēle ir atkarīga no konkurējošā piekļuves rakstura mapē. Vispārējos gadījumos bieži pietiek ar sync.Mutex vai sync.RWMutex. Specifiskos scenārijos sync.Map var nodrošināt labāku veiktspēju.