TGViewer
PRO Go PRO Go @pro_gofer · 3.3K subscribers
Post #687 694
Про sync.WaitGroup⏳

В прошлый раз остановились на неприятном: горутину запустили, а main закончился раньше, чем она успела хоть что-то сделать. Сегодня про то, как это лечится по-человечески.

Первое, что приходит в голову — заткнуть дыру задержкой.

time.Sleep(time.Second)

Работает ровно до того дня, когда сеть притормозит и секунды не хватит. А если поставить запас побольше, программа будет честно стоять на месте даже тогда, когда всё давно готово. Гадание, а не синхронизация.

Нормальный инструмент называется sync.WaitGroup. По сути это счётчик горутин, которых мы ждём.

var wg sync.WaitGroup

for _, city := range cities {
wg.Add(1)
go func(city string) {
defer wg.Done()
fetchWeather(city)
}(city)
}

wg.Wait()


Три метода, и на этом всё. Add(1) — добавили горутину, которую надо дождаться. Done() — эта закончила, счётчик минус один. Wait() — стоим здесь, пока счётчик не обнулится.

Приятная мелочь: var wg sync.WaitGroup уже готов к работе, никаких New и инициализаций. Нулевое значение и есть рабочее, в Go так устроено много чего.

defer перед wg.Done() тоже не для красоты. Если внутри горутины случится паника или ранний return, Done без defer просто не вызовется, счётчик никогда не дойдёт до нуля, и Wait будет ждать вечно. Причём программа не упадёт с ошибкой, а именно зависнет — отдельное удовольствие ловить такое в проде.

Ну и главная ловушка, на которой спотыкаются почти все. Add обязан стоять до go, а не внутри горутины.

go func() {
wg.Add(1) // так нельзяdefer wg.Done()
...
}()


Выглядит-то логично, горутина сама себя посчитала. Но main в этот момент бежит дальше и вполне может добраться до Wait раньше, чем горутина вообще стартует и что-то прибавит. Счётчик ноль, Wait решает, что ждать некого, программа идёт дальше без результатов — то есть мы вернулись ровно к той проблеме, с которой начинали, только теперь она замаскирована правильно выглядящим кодом.

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

Напоминаю, что скидка 20% на курс PRO Go Для продвинутых всё ещё действует, но остаётся всего два дня❤️
  • ❤ 1
  • 🔥 1
More from @pro_gofer
  1. Oct 13, 2026Как восстановить доступ к курсу пока Stepik недоступен🙏 Stepik сейчас недоступен, но твоё…
  2. Oct 13, 2026Друзья, доброго дня! Как многие уже заметили, Stepik уже несколько дней не работает🥺 — ав…
  3. Oct 6, 2026#memes
  4. Oct 4, 2026Где хранить данные 💾 Классическая история. Написана первая серьёзная программа — консольн…
  5. Sep 28, 2026Вайбкодеры напряглись
  6. Sep 24, 2026sql.Open 🔌 Помню, как в первый раз полез из Go в базу и минут сорок не понимал, почему вс…
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →