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.