Ответ
sync.WaitGroup
в Go — это механизм синхронизации, который позволяет горутинам ожидать завершения набора других горутин. Он предоставляет три основных метода:
-
Add(delta int)
:- Увеличивает или уменьшает внутренний счетчик
WaitGroup
на указанное значениеdelta
. - Обычно вызывается перед запуском каждой горутины, которую нужно отслеживать, с
delta = 1
. - Если счетчик становится отрицательным, это вызовет панику.
- Увеличивает или уменьшает внутренний счетчик
-
Done()
:- Уменьшает счетчик
WaitGroup
на 1. - Это эквивалентно вызову
Add(-1)
. - Обычно вызывается внутри горутины, когда она завершает свою работу, часто с использованием
defer
для гарантии выполнения.
- Уменьшает счетчик
-
Wait()
:- Блокирует выполнение текущей горутины до тех пор, пока внутренний счетчик
WaitGroup
не станет равным нулю. - Используется для ожидания завершения всех отслеживаемых горутин.
- Блокирует выполнение текущей горутины до тех пор, пока внутренний счетчик
Пример использования WaitGroup
:
package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done() // Уменьшаем счетчик на 1, когда горутина завершается
fmt.Printf("Рабочий %d начал работуn", id)
time.Sleep(time.Second) // Имитация работы
fmt.Printf("Рабочий %d закончил работуn", id)
}
func main() {
var wg sync.WaitGroup // Объявляем WaitGroup
for i := 1; i <= 3; i++ {
wg.Add(1) // Увеличиваем счетчик на 1 для каждой новой горутины
go worker(i, &wg) // Запускаем горутину
}
wg.Wait() // Блокируем main горутину, пока все рабочие не завершат работу
fmt.Println("Все рабочие завершили работу. Программа завершается.")
}