Sobes.tech
Middle

Какви mutex-и използвате, за да осигурите безопасност при работа с карти в Go?

sobes.tech AI

Отговор от AI

За да осигурите безопасност при работа с неконкурентен достъп до структури от данни, включително карти (map), в Go се използват mutex-и от пакета sync.

  • sync.Mutex: Основен mutex за взаимно изключване. Използва се за блокиране и отключване на части от кода, където се извършва четене или писане в карта.
  • sync.RWMutex: mutex с разделяем (четене) и изключителен (писане) достъп. Позволява на няколко горутини да четат от картата едновременно, но само една да пише. Идеален за сценарии, където четенето значително превъзхожда писането.

Предпочитаният вариант за съвместна и безопасна работа с карти е sync.RWMutex, тъй като осигурява по-добра производителност при множество едновременни операции за четене.

Пример за използване на 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()   // Блокиране за писане
	defer sm.mu.Unlock()
	sm.m[key] = value
}

func (sm *SafeMap) Get(key string) (int, bool) {
	sm.mu.RLock()  // Блокиране за четене
	defer sm.mu.RUnlock()
	value, ok := sm.m[key]
	return value, ok
}

Съществува и специализиран тип sync.Map, който е оптимизиран за използване в конкурентни среди без явното блокиране с mutex-и в повечето случаи, но има определени ограничения и различен API. Ако обаче е необходим по-гъвкав контрол върху блокировките или специфични сценарии за достъп, използването на sync.RWMutex върху стандартна map е честа практика.