Еще одну возможность по синхронизации горутин представляет использование типа sync.WaitGroup. Этот тип позволяет определить группу горутин, которые должны выполняться вместе как одна группа. И можно установить блокировку, которая приостановит выполнение функции, пока не завершит выполнение вся группа горутин. Например:
package main import ( "fmt" "sync" "time" ) func main() { var wg sync.WaitGroup wg.Add(2) // в группе две горутины work := func(id int) { defer wg.Done() fmt.Printf("Горутина %d начала выполнение \n", id) time.Sleep(2 * time.Second) fmt.Printf("Горутина %d завершила выполнение \n", id) } // вызываем горутины go work(1) go work(2) wg.Wait() // ожидаем завершения обоих горутин fmt.Println("Горутины завершили выполнение") }
Вначале определяем группу в виде переменной wg sync.WaitGroup
. С помощью метода Add определяем, что группа будет состоять из двух элементов:
wg.Add(2)
Число, которое передается в метод Add определяет значение внутреннего счетчика активных элементов.
Все элементы группы wg будут представлять анонимную функцию в виде переменной work, которая в качестве параметра принимает условный числовой идентификатор горутины.
Эта функция будет вызываться в виде горутин. Чтобы сигнализировать, что элемент группы завершил свое выполнение, в горутине необходимо вызвать метод Done()
:
defer wg.Done()
Вызов метода wg.Done() уменьшает внутренний счетчик активных элементов на единицу.
В самой функции work()
с помощью задержки времени на две секунды (time.Sleep(2 * time.Second)
) имитируется работа горутины
Далее вызываем две горутины:
go work(1) go work(2)
Причем количество горутин, которые вызывают метод wg.Done()
должно соответствовать количеству элементов группы wg, то есть в данном случае 2 элемента.
Затем вызывается метод Wait()
, который ожидает завершения всех горутин из группы wg:
wg.Wait()
Метод деблокирует функцию main, когда внутренний счетчик активных элементов в группе wg стает равен 0. Поэтому когда все горутины из группы wg завершат выполнение, функция main продолжит свою работу.
Результат работы программы:
Горутина 1 начала выполнение Горутина 2 начала выполнение Горутина 1 завершила выполнение Горутина 2 завершила выполнение Горутины завершили выполнение