sync.WaitGroup — счетчик активных одновременных задач. Его цель — позволить одной горутине (Wait) ждать, пока другие завершат свою работу.
Как это работает:
-
wg.Add(n) увеличивает счётчик на n (добавляем количество задач).
-
Каждая выполненная задача вызывает срабатывание wg.Done() (эквивалент Add(-1)).
-
wg.Wait() блокируется до тех пор, пока счетчик не достигнет нуля.
Что будет при отрицательном счетчике:
-
Это логическая ошибка координации.
-
Время выполнения вызывает панику (обычно: sync: negative WaitGroup counter).
-
Эта ситуация означает, что Done() вызывался больше раз, чем Add().
Почему вы не можете выполнить от Done() до Add():
-
Нарушен контракт жизненного цикла задачи.
-
Wait() может завершиться преждевременно, поскольку в момент ожидания счетчик
еще не отражает реального количества рабочих мест.
-
В худшем случае получим отрицательный счетчик и панику.
Правильная дисциплина:
-
Вызовите Add(1) перед запуском горутины.
-
Внутри горутины сразу на входе устанавливаем defer wg.Done().
-
Звоните на Wait() только после регистрации всех задач.
Заключение:
WaitGroup надежен только при строгой последовательности Add -> go -> Done -> Wait. Отрицательный счетчик и от Done() до Add() является сигналом о нарушенной модели синхронизации, что неизбежно приводит к нестабильному поведению или панике.
Пример:
Итог
sync.WaitGroup — счетчик активных одновременных задач.