Ответ
Атомарные (atomic) операции в Go — это операции, которые выполняются как единое, неделимое действие, без риска быть прерванными другим потоком (горутиной). Это гарантирует потокобезопасность при работе с разделяемыми данными без необходимости использования более медленных примитивов синхронизации, таких как мьютексы.
Пакет sync/atomic
предоставляет низкоуровневые атомарные примитивы, которые напрямую транслируются в инструкции процессора.
Ключевые преимущества:
- Производительность: Атомарные операции значительно быстрее мьютексов для простых сценариев (например, инкремент счетчика), так как они не вызывают блокировку потока и переключение контекста планировщиком.
- Отсутствие блокировок (Lock-Free): Позволяют создавать неблокирующие алгоритмы.
Основные операции в sync/atomic
:
Add
: Атомарно добавляет значение (например,AddInt64
).Load
: Атомарно читает значение.Store
: Атомарно записывает значение.Swap
: Атомарно записывает новое значение и возвращает старое.CompareAndSwap
(CAS): Атомарно сравнивает значение с ожидаемым и, если они совпадают, заменяет его новым. Это одна из самых мощных атомарных операций.
Пример использования:
import (
"fmt"
"sync"
"sync/atomic"
)
func main() {
var counter int64
var wg sync.WaitGroup
wg.Add(100)
for i := 0; i < 100; i++ {
go func() {
defer wg.Done()
// Безопасный инкремент счетчика из разных горутин
atomic.AddInt64(&counter, 1)
}()
}
wg.Wait()
// Для чтения также используем атомарную операцию
finalValue := atomic.LoadInt64(&counter)
fmt.Println("Final Counter:", finalValue) // => Final Counter: 100
}
Когда использовать:
Атомарные операции идеально подходят для реализации счетчиков, флагов состояний или для управления простыми разделяемыми переменными, где производительность критична.