За да изчакаме множество гозадачи да свършат работа, можем да ползваме чакалня.
import (
"fmt"
"sync"
"time"
)
Това е функцията, която ще изпълним във всяка гозадача.
func работник(id int) {
fmt.Printf("Работник %d започва работа.\n", id)
Заспиваме, за да наподобим тежка задача.
time.Sleep(time.Second)
fmt.Printf("Работник %d е готов.\n", id)
}
func main() {
Тази чакалня – структура от вида sync.WaitGroup –
ще ползваме, за да чакаме всички пуснати гозадачи
да свършат работа. Забележка: Ако ще подавате
чакалня на функция трябва да подадете указател
към нея.
var wg sync.WaitGroup
пускаме няколко гозадачи с помощта на
WaitGroup.Go.
for i := 1; i <= 5; i++ {
wg.Go(func() {
работник(i)
})
}
Спираме програмата, докато всички гозадачи, пуснати
от wg станат готови. Гозадачата е готова, когато
функцията, която тя извиква, се изпълни.
wg.Wait()
Забележте, че при този подход няма ясен начин как да предадем вероятните грешки от работниците. За по-сложни случаи може да ползвате пакета errgroup.
}
$ go run waitgroups.go
Работник 5 започва работа.
Работник 3 започва работа.
Работник 4 започва работа.
Работник 2 започва работа.
Работник 1 започва работа.
Работник 4 е готов.
Работник 3 е готов.
Работник 5 е готов.
Работник 2 е готов.
Работник 1 е готов.
Редът на тръгващи и спиращи работници може да е различен при всяко пускане.
Следващ пример: Ограничителни ставки.