Waitgroups

WaitGroups|WaitGroups #

// Для ожидания выполнения нескольких горутин, мы можем
// использовать встроенную конструкцию *WaitGroup*.

package main

import (
	"fmt"
	"sync"
	"time"
)

// Эта функция, которую мы будем запускать в каждой
// горутине. Обратите внимание, что WaitGroup должна
// быть передана в функцию по указателю.
func worker(id int, wg *sync.WaitGroup) {
	fmt.Printf("Worker %d starting\n", id)

	// Sleep симулирует тяжелую задачу.
	time.Sleep(time.Second)
	fmt.Printf("Worker %d done\n", id)

	// Оповестить WaitGroup что воркер выполнился
	wg.Done()
}

func main() {

	// Эта WaitGroup используется для ожидания выполнения
	// всех горутинё запущенных здесь.
	var wg sync.WaitGroup

	// Запускаем несколько горутин и инкрементируем счетчик
	// в WaitGroup для каждой запущенной горутины.
	for i := 1; i <= 5; i++ {
		wg.Add(1)
		go worker(i, &wg)
	}

	// Блокируем звершение программы до момента, пока
	// счетчик WaitGroup снова не станет равным 0.
	// Это будет означать, что все горутины выполнились.
	wg.Wait()
}
$ go run waitgroups.go
Worker 5 starting
Worker 3 starting
Worker 4 starting
Worker 1 starting
Worker 2 starting
Worker 4 done
Worker 1 done
Worker 2 done
Worker 5 done
Worker 3 done

# Порядок воркеров начинающихся и выполненных, вероятно
# будет изменяться при каждом запуске.