Логотип YeaHub

База вопросов

Собеседования

Тренажёр

База ресурсов

Обучение

Навыки

Задачи

Войти

Выбери, каким будет IT завтра — вместе c нами!

YeaHub — это полностью открытый проект, призванный объединить и улучшить IT-сферу. Наш исходный код доступен для просмотра на GitHub. Дизайн проекта также открыт для ознакомления в Figma.

© 2026 YeaHub

AI info

Карта сайта

Документы

Медиа

Назад
Вопрос про Golang: goroutine, mutex, channel, waitgroup, sync

Какие примитивы синхронизации ты знаешь в Go?

Вопрос проверяет знание базовых механизмов синхронизации горутин в Go, необходимых для написания безопасного конкурентного кода.

Короткий ответ

В Go есть несколько примитивов синхронизации: мьютексы (sync.Mutex, sync.RWMutex) для защиты общих данных, каналы (chan) для обмена данными между горутинами, sync.WaitGroup для ожидания завершения группы горутин, sync.Once для однократного выполнения, sync.Cond для условной синхронизации и атомарные операции из пакета sync/atomic.

Длинный ответ

Основные примитивы синхронизации в Go

Go предоставляет богатый набор инструментов для синхронизации горутин, каждый из которых решает свою задачу. Основные примитивы включают мьютексы, каналы, WaitGroup, Once, Cond и атомарные операции.

Мьютексы (sync.Mutex и sync.RWMutex)

Мьютекс (Mutex) — это блокировка, которая позволяет только одной горутине одновременно выполнять критическую секцию кода. RWMutex (Read-Write Mutex) оптимизирован для сценариев, где много читателей и мало писателей: несколько горутин могут одновременно читать, но запись блокирует всех.

var mu sync.Mutex
var counter int

func increment() {
    mu.Lock()
    counter++
    mu.Unlock()
}

Каналы (chan)

Каналы — это типизированные трубы для передачи данных между горутинами. Они могут быть буферизированными или небуферизированными. Небуферизированный канал блокирует отправителя до получения данных получателем, обеспечивая синхронизацию.

ch := make(chan int)
go func() {
    ch <- 42
}()
value := <-ch // блокируется, пока не придет значение

WaitGroup

sync.WaitGroup используется для ожидания завершения набора горутин. Вызов Add увеличивает счетчик, Done уменьшает, а Wait блокирует выполнение до обнуления счетчика.

var wg sync.WaitGroup
for i := 0; i < 5; i++ {
    wg.Add(1)
    go func(id int) {
        defer wg.Done()
        fmt.Println(id)
    }(i)
}
wg.Wait()

Once и Cond

sync.Once гарантирует однократное выполнение функции, даже при вызове из нескольких горутин. sync.Cond позволяет горутинам ждать определенного условия и уведомлять друг друга о его наступлении.

Атомарные операции (sync/atomic)

Пакет atomic предоставляет низкоуровневые атомарные операции для работы с памятью без блокировок: Add, Load, Store, CompareAndSwap и другие. Они эффективнее мьютексов для простых счетчиков и флагов.

var counter int64
atomic.AddInt64(&counter, 1)

Вывод: Выбор примитива зависит от задачи: для защиты общих данных используйте Mutex или RWMutex, для обмена данными — каналы, для ожидания группы горутин — WaitGroup, для однократных инициализаций — Once, для сложных условий — Cond, а для простых счетчиков — атомарные операции.

  • Аватар

    Golang Guru

    Maxim Lukyanov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.

Уровень

  • Рейтинг:

    4

  • Сложность:

    5

Навыки

  • Golang

    Golang

Ключевые слова

#goroutine

#mutex

#channel

#waitgroup

#sync

Подпишись на Golang Developer в телеграм

  • Аватар

    Golang Guru

    Maxim Lukyanov

    Guru – это эксперты YeaHub, которые помогают развивать комьюнити.