0Pricing
Go Academy · Урок

sync.WaitGroup

Ожидание завершения группы горутин

«sync.WaitGroup» — бесплатный урок Go Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Go Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Go Academy содержит 4 уроков всего.

Назначение

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

Базовое использование

Вызывайте Add перед запуском каждой горутины, Done в конце каждой горутины (через defer), а Wait после запуска всех горутин.

var wg sync.WaitGroup
for _, item := range items {
    wg.Add(1)
    go func(v Item) {
        defer wg.Done()
        process(v)
    }(item)
}
wg.Wait()

Add должен выполняться до запуска горутины

Вызовите wg.Add(1) перед go func(), а не внутри горутины. Иначе Wait может завершиться до того, как горутина зарегистрирует себя.

Распространённая ошибка: захват переменной цикла

Передавайте переменную цикла как аргумент функции горутины, а не через замыкание, чтобы все горутины не использовали одну и ту же переменную.

for _, v := range items {
    wg.Add(1)
    go func(item Item) { // correct: copy
        defer wg.Done()
        process(item)
    }(v)
}

Повторное использование WaitGroup

WaitGroup можно повторно использовать после возврата из Wait, но только если все предыдущие вызовы Done завершились. Не используйте его повторно одновременно с незавершёнными вызовами Done.

WaitGroup и результаты

WaitGroup не собирает результаты — объедините его с каналом или срезом (с мьютексом), чтобы собрать вывод горутин.

results := make([]Result, len(items))
for i, item := range items {
    wg.Add(1)
    go func(idx int, v Item) {
        defer wg.Done()
        results[idx] = process(v)
    }(i, item)
}
wg.Wait()

Add с общим количеством

Можно передать общее количество в одном вызове Add перед циклом — это немного эффективнее, чем один Add для каждой горутины.

wg.Add(len(items))
for _, item := range items {
    go func(v Item) { defer wg.Done(); process(v) }(item)
}

Не копируйте WaitGroup

Как и мьютекс, WaitGroup нельзя копировать после первого использования. Передавайте его по указателю или встраивайте в структуру, передаваемую по указателю.

WaitGroup и errgroup

golang.org/x/sync/errgroup оборачивает WaitGroup и добавляет передачу ошибок. Предпочитайте errgroup, если сбой любой горутины должен остановить остальные.

Объединение с контекстом

Используйте errgroup.WithContext, чтобы получить и семантику WaitGroup, и контекст, который отменяется при первой ошибке и корректно останавливает все горутины.

g, ctx := errgroup.WithContext(context.Background())
g.Go(func() error { return doWork(ctx) })
if err := g.Wait(); err != nil { log.Fatal(err) }

Нулевое значение можно использовать

Нулевое значение sync.WaitGroup готово к использованию — конструктор не нужен. Просто объявите его и вызовите Add.

Быстрая проверка

Что произойдёт, если вызвать wg.Add(1) внутри горутины, а не перед её запуском?

Повторение: sync.WaitGroup

Основные моменты:

  • Add перед запуском горутины; Done через defer внутри горутины
  • Wait блокирует выполнение, пока счётчик не достигнет нуля
  • Никогда не копируйте WaitGroup и не вызывайте Add внутри горутины
  • Используйте errgroup для передачи ошибок

Часто задаваемые вопросы

Урок «sync.WaitGroup» бесплатный?

Да — полный текст урока «sync.WaitGroup» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Go Academy, подпишись на CoddyKit PRO. Курс Go Academy содержит 4 уроков всего.

Чему я научусь в уроке «sync.WaitGroup»?

Ожидание завершения группы горутин Ты практикуешь Go Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Go Academy?

Предыдущий опыт не требуется. Go Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «sync.WaitGroup»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Go Academy?

Да. Каждый урок Go Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. sync.Mutex и sync.RWMutex
  2. sync.WaitGroup
  3. sync.Once и sync.Map
  4. Детектор состязаний и безопасные шаблоны
← Назад к Go Academy