Основные инструменты конкурентности в Go — просто и по делу
Горутина — это легковесный поток, которым управляет Go Runtime, а не операционная система. Создать горутину в тысячи раз дешевле, чем обычный поток ОС.
Вы один роете котлован, мешаете бетон, кладёте кирпичи. Пока ждёте доставку — просто стоите. Дом строится очень долго.
Нанять несколько бригад — эффективно, но дорого. Каждая требует своей техники и документов. 1000 бригад — разорение.
go перед вызовом функции.main — вся программа останавливается, даже если другие горутины ещё не закончили работу.sync.WaitGroup решает главную проблему: как сообщить программе, что нужно подождать завершения всех запущенных горутин.
wg.Add(N) — добавить задачиwg.Done() — задача выполненаdefer wg.Done() — это гарантирует вызов даже при ошибке.wg.Wait() — ждать пустого спискаwg.Add() до запуска горутины через go. Иначе Wait() может сработать раньше, чем горутина успеет зарегистрироваться.Гонка данных возникает, когда две или более горутины обращаются к одному участку памяти одновременно, и хотя бы одна из них записывает данные. Результат становится непредсказуемым.
Мьютексы защищают общее состояние — сложные структуры данных, кэши, конфигурации — от одновременного доступа нескольких горутин.
RWMutex.Mutex.«Атомарный» означает «неделимый». Атомарная операция гарантированно выполняется как единое целое — другие горутины не могут увидеть её «наполовину выполненной».
Обычный counter++ — это три шага: прочитать → увеличить → записать. Гонка данных происходит в «щели» между этими шагами. Атомарная операция выполняет все три шага за один приём на уровне процессора.
| Плюсы | Минусы |
|---|---|
| Максимальная производительность для простых операций | Сложнее читать и отлаживать |
| Не блокирует горутины, нет переключения контекста | Работает только с примитивными типами (int32, int64, указатели) |
| Прямой доступ к инструкциям процессора | Неправильное использование приводит к редким и сложным багам |
| Ситуация | Инструмент | Почему |
|---|---|---|
| Сложная структура данных (мапа, слайс) | sync.Mutex |
atomic не умеет работать со сложными типами |
| Много читателей, мало писателей | sync.RWMutex |
Читатели не блокируют друг друга |
| Простой счётчик, производительность критична | sync/atomic |
Нет накладных расходов на блокировку |
| Вы не уверены, что выбрать | sync.Mutex |
Безопаснее, проще, правильно в 99% случаев |
sync.Mutex. Переходите на sync/atomic только при доказанном узком месте в производительности — например, после профилирования через pprof.