Ответ
Метод Wait() типа sync.WaitGroup блокирует выполнение текущей горутины до тех пор, пока внутренний счетчик WaitGroup не станет равен нулю.
Это основной механизм для синхронизации и ожидания завершения группы горутин. Главная горутина (или любая другая) может вызвать wg.Wait(), чтобы дождаться, пока все "рабочие" горутины выполнят свою задачу.
Жизненный цикл WaitGroup:
Add(n): Перед запуском горутин счетчик увеличивается наn(количество горутин, которые нужно ожидать).- Запуск горутин: В каждой горутине с помощью
deferвызываетсяDone(). Done(): Уменьшает внутренний счетчик на единицу.Wait(): Блокирует и ждет, пока счетчик не обнулится.
Пример:
package main
import (
"fmt"
"sync"
"time"
)
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() {
var wg sync.WaitGroup
for i := 1; i <= 3; i++ {
wg.Add(1) // Увеличиваем счетчик перед запуском горутины
go worker(i, &wg)
}
fmt.Println("Основная горутина ждет завершения всех рабочих...")
wg.Wait() // Блокировка до тех пор, пока счетчик не станет 0
fmt.Println("Все рабочие завершили выполнение.")
}Важно: Вызов Done() при счетчике, равном нулю, или уменьшение счетчика до отрицательного значения вызовет панику.