Sobes.tech
Middle+

Como proteger-se de erros ao escrever de forma concorrente em um mapa?

sobes.tech IA

Resposta da IA

Para proteger contra erros ao escrever concorrente em map em Golang, que não são seguros para múltiplas threads por padrão, usam-se os seguintes mecanismos:

  • sync.Mutex: Bloqueia o map antes de escrever e desbloqueia após.

    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: Permite leitura simultânea do map por várias goroutines, mas bloqueia a escrita durante leitura ou escrita 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 de escrita
        defer sm.mu.Unlock()
        sm.data[key] = value
    }
    
    func (sm *SafeMapRWMutex) Get(key string) (int, bool) {
        sm.mu.RLock() // Lock de leitura
        defer sm.mu.RUnlock()
        val, ok := sm.data[key]
        return val, ok
    }
    
  • sync.Map: Tipo especializado thread-safe, otimizado para cenários onde o conjunto de chaves é relativamente estável e as escritas são raras, ou quando várias goroutines leem e escrevem para conjuntos disjuntos de chaves.

    import "sync"
    
    var safeMap sync.Map // Declaração
    
    func UseSyncMap() {
        safeMap.Store("key1", 10) // Escrita
        if val, ok := safeMap.Load("key1"); ok { // Leitura
            // Usar val
        }
        safeMap.Delete("key1") // Deletar
    }
    

Comparação de abordagens:

Mecanismo Vantagens Desvantagens Aplicação
sync.Mutex Simples de usar Bloqueia todas as operações na escrita Cenários simples, onde a concorrência não é alta ou leitura/escrita são similares.
sync.RWMutex Permite leitura paralela Mais complexo que sync.Mutex. A escrita bloqueia a leitura e outras escritas. Cenários com leitura frequente e escrita rara.
sync.Map Otimizado para certos cenários Tem API limitada. Pode ser mais lento que Mutex se o acesso for totalmente aleatório. Cenários com chaves relativamente estáveis ou conjuntos disjuntos de chaves para diferentes goroutines.

A escolha de uma abordagem específica depende da natureza do acesso concorrente ao map. Para casos gerais, sync.Mutex ou sync.RWMutex geralmente são suficientes. Para cenários específicos, sync.Map pode oferecer melhor desempenho.