Ответ
Метод 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()
при счетчике, равном нулю, или уменьшение счетчика до отрицательного значения вызовет панику.