Ожидание группы горутин в Go
Счетчик группы ждет, пока каждая запущенная
функция не сообщит о конце. Перед запуском
увеличивают ожидание, в самой ветке в
отложенной функции уменьшают счетчик, а
в main блокируются, пока все ветки
не отметились.
Тип sync.WaitGroup передают по указателю,
иначе копия не увидит изменений. Три шага
идут в строгом порядке: добавить ожидание
до запуска, отметить готовность при выходе,
затем ждать в вызывающем коде.
Соберем запуск с ожиданием:
package main
import (
"fmt"
"sync"
)
func work(wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println("done")
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
go work(&wg)
wg.Wait()
fmt.Println("main end")
}
На экране сначала "done", затем
"main end". Wait не возвращает
управление, пока Done не сработает
в ветке.
Отложенный Done удобен, если функция
завершится и обычным return, и через
аварийный останов после перехвата внутри
самой ветки:
package main
import (
"fmt"
"sync"
)
func task(wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println("task")
}
func main() {
var wg sync.WaitGroup
wg.Add(1)
go task(&wg)
wg.Wait()
}
Дана функция:
func show(wg *sync.WaitGroup) {
defer wg.Done()
fmt.Println("ok")
}
В main объявите группу, добавьте
одно ожидание, запустите show
отдельной веткой и дождитесь конца перед
печатью "exit".
Дан следующий код:
var wg sync.WaitGroup
wg.Add(1)
go func() {
fmt.Println("x")
}()
wg.Wait()
Скажите, почему Wait здесь не
закончится.
Скажите, зачем в work из первого
примера Done ставят в отложенной
функции, а не в конце тела.