Sobes.tech
Middle+

Ինչպե՞ս պաշտպանվել մրցակցային գրառման սխալներից քարտեզում։

sobes.tech AI

Պատասխան AI-ից

Կարողության պաշտպանություն սխալներից՝ concurrent գրառման ժամանակ map-ում Golang-ում, որոնք ըստ նախնական կարգավորումների չեն ապահովված թելային անվտանգությամբ, օգտագործվում են հետևյալ մեխանիզմները:

  • sync.Mutex: Map-ի փակումը գրառման առաջ և բացումը՝ հետո:

    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: Միաժամանակ ընթերցել Map-ից մի քանի գորութին, բայց արգելել գրառումը՝ միաժամանակ ընթերցման կամ գրառման ժամանակ:

    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() // Գրառման արգելք
        defer sm.mu.Unlock()
        sm.data[key] = value
    }
    
    func (sm *SafeMapRWMutex) Get(key string) (int, bool) {
        sm.mu.RLock() // Ընթերցման արգելք
        defer sm.mu.RUnlock()
        val, ok := sm.data[key]
        return val, ok
    }
    
  • sync.Map: Մասնագիտացված, թելային անվտանգ տիպ, օպտիմիզացված այն սցենարների համար, որտեղ բանալիների հավաքածուն հարաբերականորեն կայուն է, գրառումները հազվադեպ են, կամ երբ մի քանի գորութիններ ընթերցում և գրառում են տարբեր disjunctiv հավաքածուներով:

    import "sync"
    
    var safeMap sync.Map // Դեկլարացիա
    
    func UseSyncMap() {
        safeMap.Store("key1", 10) // Գրառում
        if val, ok := safeMap.Load("key1"); ok { // Ընթերցում
            // Օգտագործել val
        }
        safeMap.Delete("key1") // Ջնջում
    }
    

Համեմատություն մեխանիզմների միջև:

Մեխանիզմ Առավելություններ Недостатки Կիրառում
sync.Mutex Պարզ է օգտագործել Բլոկավորում է բոլոր գործողությունները գրառման ժամանակ Պարզ սցենարներ, որտեղ մրցակցությունը ցածր է կամ ընթերցում-գրառումը մոտավորապես հավասար են։
sync.RWMutex Ինքնատիպ ընթերցում թույլ է տալիս Ավելի բարդ, քան sync.Mutex. Գրառումը բլոկավորում է ընթերցումը և մյուս գրառումները Սցենարներ, որտեղ հաճախ է ընթերցում և հազվադեպ գրառում։
sync.Map Բարելավված որոշ սցենարների համար Հ محدود API. Может быть медленнее Mutex, если доступ полностью случайный. Սցենարներ, որտեղ բանալիների հավաքածուն հարաբերականորեն կայուն է կամ disjunctiv հավաքածուներ։

Ընտրությունը կախված է կոնկրետ մրցակցային մուտքի բնույթից։ Ընդհանուր դեպքերում հաճախ բավարար է sync.Mutex կամ sync.RWMutex։ Սպեցիֆիկ սցենարների համար sync.Map կարող է ապահովել ավելի լավ կատարողականություն։