WaitGroup ожидает завершения коллекции goroutine. Основная goroutine вызывает Add, чтобы установить количество goroutine, которых необходимо ожидать. Затем каждая из goroutine запускается и вызывает Done, когда завершается. В то же время, Wait может быть использован, чтобы блокировать, пока все goroutine не завершились.
WaitGroup нельзя копировать после первого использования.
В следующем примере выполняются конкурентные запросы по нескольким URL-адресам с использованием WaitGroup для блокировки исполнения до тех пор, пока все запросы не будут завершены.
package main
import (
"fmt"
"sync"
)
type httpPkg struct{}
func (httpPkg) Get(url string) {}
var http httpPkg
func main() {
var wg sync.WaitGroup
var urls = []string{
"http://www.golang.org/",
"http://www.google.com/",
"http://www.example.com/",
}
fmt.Println("Начинаем выполнять запросы")
for _, url := range urls {
// Увеличиваем WaitGroup счетчик.
wg.Add(1)
// Запускаем goroutine для выполения запроса по URL.
go func(url string) {
// Уменьшаем счетчик когда goroutine завершается.
defer wg.Done()
// Выполеняем запрос по URL.
http.Get(url)
fmt.Println(url)
}(url)
}
// Ожидаем пока все HTTP запросы завершатся.
wg.Wait()
fmt.Println("Все запросы выполнены")
}
Вывод:
Начинаем выполнять запросы
http://www.example.com/
http://www.golang.org/
http://www.google.com/
Все запросы выполнены
Запустить пример в песочнице play.golang.org
Метод func(*WaitGroup) Add
func (wg *WaitGroup) Add(delta int)
Add добавляет delta, которая может быть отрицательной, к счетчику WaitGroup. Если счетчик обнуляется, все goroutine, заблокированные Wait, освобождаются. Если счетчик становится отрицательным, Add вызывает panic.
Обратите внимание, что вызовы с положительной delta, которые происходят, когда счетчик равен нулю, должны происходить до Wait. Вызовы с отрицательной delta или вызовы с положительной delta, которые начинаются, когда счетчик больше нуля, могут происходить в любое время. Как правило, это означает, что вызовы Add должны выполняться перед утверждением, создающим goroutine или другим событием, которое следует ожидать. Если WaitGroup повторно используется для ожидания нескольких независимых наборов событий, новые вызовы Add должны произойти после того, как все предыдущие вызовы Wait будут возвращены.
Метод func(*WaitGroup) Done
func (wg *WaitGroup) Done()
Done уменьшает счетчик WaitGroup на один.
Метод func(*WaitGroup) Wait
func (wg *WaitGroup) Wait()
Wait блокирует исполнение потока до тех пор пока счетчик WaitGroup не обнулится.
Читайте также:
- Модель памяти Go
- Эффективный Go: параллелизм, go-процедуры (goroutines)
- Использование sync.Once для однократного вызова функций из конкурентных go-процедур
Комментариев нет:
Отправить комментарий