Sobes.tech
Back to questions
Middle+
4

Можно ли вызвать WaitGroup.Add внутри горутины, а Done в конце? Будет ли это работать корректно?

Companies where asked
YadroYadro

Answer from AI

sobes.tech AI

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

Если вы вызываете Add внутри горутины, которая ещё не запущена или не начала работу, а в основном потоке уже вызвали Wait, то есть риск, что Wait начнёт ожидать до того, как счётчик будет увеличен, и завершится раньше времени — это приведёт к ошибкам синхронизации.

Правильный подход:

  • Вызывать Add до запуска горутин, чтобы гарантировать, что счётчик установлен.
  • Внутри горутин вызывать только Done.

Пример корректного использования:

var wg sync.WaitGroup
wg.Add(3) // заранее увеличиваем счётчик

for i := 0; i < 3; i++ {
    go func() {
        defer wg.Done()
        // работа горутины
    }()
}

wg.Wait()

Если же Add вызывается внутри горутины, то Wait может быть вызван до увеличения счётчика, что приведёт к панике или неправильному ожиданию.

Итого: не рекомендуется вызывать Add внутри горутины, если Wait уже может быть вызван.