Sobes.tech
Middle

Que mutexes você usa para garantir a segurança ao trabalhar com mapas em Go?

sobes.tech IA

Resposta da IA

Para garantir a segurança ao trabalhar com acesso não concorrente a estruturas de dados, incluindo mapas (map), em Go são utilizados mutexes do pacote sync.

  • sync.Mutex: Mutex básico para exclusão mútua. Usado para bloquear e desbloquear seções de código onde ocorre leitura ou escrita no mapa.
  • sync.RWMutex: Mutex com acesso compartilhado (leitura) e exclusivo (escrita). Permite que várias goroutines leiam do mapa simultaneamente, mas apenas uma escreva. É ideal para cenários onde as leituras são muito mais frequentes que as escritas.

A opção preferida para trabalhar com mapas de forma concorrente e segura é sync.RWMutex, pois oferece melhor desempenho em operações de leitura simultâneas.

Exemplo de uso de sync.RWMutex:

import (
	"sync"
)

type SafeMap struct {
	mu sync.RWMutex
	m  map[string]int
}

func NewSafeMap() *SafeMap {
	return &SafeMap{
		m: make(map[string]int),
	}
}

func (sm *SafeMap) Set(key string, value int) {
	sm.mu.Lock()   // Bloqueio para escrita
	defer sm.mu.Unlock()
	sm.m[key] = value
}

func (sm *SafeMap) Get(key string) (int, bool) {
	sm.mu.RLock()  // Bloqueio para leitura
	defer sm.mu.RUnlock()
	value, ok := sm.m[key]
	return value, ok
}

Também existe um tipo especializado sync.Map, que é otimizado para uso concorrente sem bloqueio explícito na maioria dos casos, mas possui certas limitações e uma API diferente. No entanto, se for necessário um controle mais flexível sobre os bloqueios ou cenários de acesso específicos, o uso de sync.RWMutex sobre um map padrão é uma prática comum.