sync.WaitGroup.Add
Метод Add типа sync.WaitGroup увеличивает внутренний счетчик
ожидаемых горутин на переданное значение. Обычно его вызывают перед
запуском каждой новой горутины, чтобы указать, что нужно дождаться ее
завершения. В качестве параметра метод принимает целое число int,
на которое будет увеличен счетчик.
Важно помнить, что вызов Add должен происходить до того, как
запущенная горутина вызовет Done, иначе можно получить панику
из-за отрицательного счетчика. Обычно Add вызывают непосредственно
перед оператором go.
Синтаксис
var wg sync.WaitGroup
wg.Add(delta int)
Пример
Давайте запустим две горутины и дождемся их завершения с помощью
WaitGroup. Для каждой горутины вызываем Add с аргументом 1:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
for i := 1; i <= 2; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
fmt.Printf("Goroutine %d started\n", id)
time.Sleep(time.Millisecond * 100)
fmt.Printf("Goroutine %d finished\n", id)
}(i)
}
wg.Wait()
fmt.Println("All goroutines finished")
}
Результат выполнения кода:
"Goroutine 2 started"
"Goroutine 1 started"
"Goroutine 2 finished"
"Goroutine 1 finished"
"All goroutines finished"
Пример
Метод Add можно вызвать один раз с общим количеством горутин,
если их количество известно заранее. Например, запустим 3 горутины:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
goroutines := 3
wg.Add(goroutines)
for i := 0; i < goroutines; i++ {
go func(id int) {
defer wg.Done()
fmt.Printf("Worker %d done\n", id)
}(i)
}
wg.Wait()
fmt.Println("All workers completed")
}
Результат выполнения кода:
"Worker 2 done"
"Worker 0 done"
"Worker 1 done"
"All workers completed"
Пример
Если счетчик WaitGroup уже равен нулю, а вы вызываете Add
с отрицательным значением, это вызовет панику. В следующем примере
мы ошибочно вызываем Add с отрицательным значением после
завершения работы:
package main
import (
"fmt"
"sync"
)
func main() {
var wg sync.WaitGroup
wg.Add(1)
go func() {
defer wg.Done()
fmt.Println("Goroutine done")
}()
wg.Wait()
// Попытка уменьшить счетчик после завершения
wg.Add(-1)
fmt.Println("This will panic")
}
Результат выполнения кода:
"Goroutine done"
"panic: sync: negative WaitGroup counter"
Смотрите также
-
тип
sync.WaitGroup,
который предоставляет механизм ожидания завершения горутин -
метод
sync.WaitGroup.Done,
который уменьшает счетчик WaitGroup на единицу -
метод
sync.WaitGroup.Wait,
который блокирует выполнение до обнуления счетчика -
тип
sync.Once,
который гарантирует однократное выполнение функции