Sobes.tech
Middle+

¿Cómo protegerse de errores en la escritura concurrente en un mapa?

sobes.tech AI

Respuesta de la IA

Para protegerse de errores en escrituras concurrentes en map en Golang, que no son seguros para múltiples hilos por defecto, se utilizan los siguientes mecanismos:

  • sync.Mutex: Bloquea el map antes de escribir y lo desbloquea despué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 leer del map simultáneamente por varias goroutines, pero bloquea la escritura durante la lectura o escritura concurrente.

    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() // Bloqueo de escritura
        defer sm.mu.Unlock()
        sm.data[key] = value
    }
    
    func (sm *SafeMapRWMutex) Get(key string) (int, bool) {
        sm.mu.RLock() // Bloqueo de lectura
        defer sm.mu.RUnlock()
        val, ok := sm.data[key]
        return val, ok
    }
    
  • sync.Map: Tipo especializado seguro para múltiples hilos, optimizado para escenarios donde el conjunto de claves es relativamente estable y las escrituras son raras, o cuando varias goroutines leen y escriben para conjuntos disjuntos de claves.

    import "sync"
    
    var safeMap sync.Map // Declaración
    
    func UseSyncMap() {
        safeMap.Store("key1", 10) // Escritura
        if val, ok := safeMap.Load("key1"); ok { // Lectura
            // Usar val
        }
        safeMap.Delete("key1") // Eliminación
    }
    

Comparación de enfoques:

Mecanismo Ventajas Desventajas Aplicación
sync.Mutex Sencillo de usar Bloquea todas las operaciones en escritura Escenarios simples donde la concurrencia no es alta o la lectura/escritura son similares.
sync.RWMutex Permite lectura paralela Más complejo que sync.Mutex. La escritura bloquea la lectura y otras escrituras. Escenarios con lectura frecuente y escritura rara.
sync.Map Optimizado para ciertos escenarios Tiene API limitada. Puede ser más lento que Mutex si el acceso es completamente aleatorio. Escenarios con claves relativamente estables o conjuntos disjuntos de claves para diferentes goroutines.

La elección de un enfoque específico depende de la naturaleza del acceso concurrente al map. Para casos generales, a menudo basta con sync.Mutex o sync.RWMutex. Para escenarios específicos, sync.Map puede ofrecer mejor rendimiento.