Sobes.tech
Middle+

Come proteggersi dagli errori durante la scrittura concorrente in una mappa?

sobes.tech AI

Risposta dell'AI

Per proteggersi dagli errori durante le scritture concorrenti in map in Golang, che non sono thread-safe di default, vengono utilizzati i seguenti meccanismi:

  • sync.Mutex: Blocca la mappa prima della scrittura e la sblocca dopo.

    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: Permette di leggere contemporaneamente da più goroutine, ma blocca la scrittura durante la lettura o scrittura concorrente.

    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() // Lock di scrittura
        defer sm.mu.Unlock()
        sm.data[key] = value
    }
    
    func (sm *SafeMapRWMutex) Get(key string) (int, bool) {
        sm.mu.RLock() // Lock di lettura
        defer sm.mu.RUnlock()
        val, ok := sm.data[key]
        return val, ok
    }
    
  • sync.Map: Tipo specializzato thread-safe, ottimizzato per scenari in cui il set di chiavi è relativamente stabile e le scritture sono rare, o quando più goroutine leggono e scrivono per set di chiavi disgiunti.

    import "sync"
    
    var safeMap sync.Map // Dichiarazione
    
    func UseSyncMap() {
        safeMap.Store("key1", 10) // Scrittura
        if val, ok := safeMap.Load("key1"); ok { // Lettura
            // Usa val
        }
        safeMap.Delete("key1") // Cancellazione
    }
    

Confronto tra approcci:

Meccanismo Vantaggi Svantaggi Applicazione
sync.Mutex Semplice da usare Blocca tutte le operazioni in scrittura Scenari semplici, dove la concorrenza non è elevata o le operazioni di lettura/scrittura sono simili.
sync.RWMutex Permette la lettura parallela Più complesso di sync.Mutex. La scrittura blocca la lettura e altre scritture. Scenari con frequente lettura e rara scrittura.
sync.Map Ottimizzato per scenari specifici Ha API limitata. Potrebbe essere più lento di Mutex se l'accesso è completamente casuale. Scenari con chiavi relativamente stabili o set disgiunti di chiavi per diverse goroutine.

La scelta di un approccio specifico dipende dalla natura dell'accesso concorrente alla mappa. Per casi generali, spesso basta sync.Mutex o sync.RWMutex. Per scenari specifici, sync.Map può offrire migliori prestazioni.