Ответ
Mutex
(мьютекс) и atomic
операции — это два механизма для управления конкурентным доступом к данным, но они работают на разных уровнях и предназначены для разных задач.
Сравнительная таблица
Характеристика | sync/atomic | sync.Mutex |
---|---|---|
Уровень | Низкоуровневый, аппаратный | Высокоуровневый, на уровне ОС/рантайма |
Что защищает | Отдельные примитивные типы (int32 , int64 , uintptr , unsafe.Pointer ) | Произвольные участки кода (критические секции), которые могут содержать сложные структуры данных |
Принцип работы | Использует атомарные инструкции процессора (например, Compare-And-Swap) | Блокирует горутину, если мьютекс занят, и планировщик переключает её на другую |
Производительность | Очень быстрый, без блокировок (lock-free) | Медленнее из-за накладных расходов на блокировку и переключение контекста |
Когда что использовать?
Используйте atomic
для:
- Простых операций, таких как инкремент/декремент счетчиков, установки флагов или безопасного чтения/записи указателя.
- Ситуаций, где производительность критически важна и можно обойтись без сложных блокировок.
// Потокобезопасный счетчик
var counter int64
atomic.AddInt64(&counter, 1)
// Безопасное чтение значения
val := atomic.LoadInt64(&counter)
Используйте Mutex
для:
- Защиты сложных структур данных (мапы, слайсы, структуры).
- Выполнения нескольких операций над данными как единой атомарной транзакции (например, прочитать значение, изменить его и записать обратно).
var mu sync.Mutex
var data = make(map[string]int)
// Защита нескольких операций
mu.Lock()
data["requests"]++
data["last_ts"] = time.Now().Unix()
mu.Unlock()
Вывод: atomic
— это легковесный инструмент для простых, атомарных модификаций примитивов. Mutex
— более мощный, но и более "тяжелый" механизм для защиты сложных операций и структур данных.