Go за Прикладом: Групи Очікування (WaitGroups)

Щоб очікувати на закінчення роботи кількох горутин, ми можемо скористатись групою очікування.

package main
import (
    "fmt"
    "sync"
    "time"
)

Це функція, яку ми виконаємо в кожній горутині. Зауважте, що WaitGroup має бути передано до функції - як вказівник.

func worker(id int, wg *sync.WaitGroup) {

Дамо знати групі очікування, що горутина відпрацювала.

    defer wg.Done()
    fmt.Printf("Воркер %d стартує\n", id)

Імітуємо деяку важку роботу.

    time.Sleep(time.Second)
    fmt.Printf("Воркер %d завершено\n", id)
}
func main() {

Ми скористаємось WaitGroup для очікування результату роботи усіх горутин.

    var wg sync.WaitGroup

Збільшимо лічильник Групи Очікування для кожної запущеної горутинки.

    for i := 1; i <= 5; i++ {
        wg.Add(1)
        go worker(i, &wg)
    }

Група Очікування блокує виконання до моменту поки лічильник знову не буде відкатане до позначки 0.

    wg.Wait()
}

Порядок старту та завершення, скоріше за все, буде іншим.

$ go run waitgroups.go
Воркер 5 стартує
Воркер 1 стартує
Воркер 3 стартує
Воркер 4 стартує
Воркер 2 стартує
Воркер 5 завершено
Воркер 1 завершено
Воркер 2 завершено
Воркер 3 завершено
Воркер 4 завершено

Наступний приклад: Взаємні Виключення (Mutexes).