Что такое WaitGroup

`sync.WaitGroup` — это структура из пакета `sync`, которая используется для синхронизации работы множества горутин. Она позволяет программе дождаться завершения набора горутин, прежде чем продолжить выполнение. Это полезно в ситуациях, когда одна часть программы должна подождать, пока другие части, работающие параллельно, завершат выполнение своих задач.

Как он работает

Использует счётчик, который инкрементируется для каждой новой задачи и декрементируется, когда задача завершается. Когда счётчик достигает нуля, это сигнализирует о том, что все задачи завершены. Вот основные методы:

1. Add: Увеличивает счётчик на заданное число. Этот метод следует вызывать перед запуском горутины или набора горутин.
2. Done: Уменьшает счётчик на единицу, сигнализируя о завершении горутины. Обычно вызывается в конце горутины.
3. Wait: Блокирует выполнение, пока его счётчик не станет равен нулю, т.е. пока все горутины не завершат выполнение.

Давайте рассмотрим пример, который демонстрирует его использование для синхронизации нескольких горутин:

```go
package main

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

func worker(id int, wg *sync.WaitGroup) {
    defer wg.Done() // Вызов Done в defer гарантирует, что счётчик уменьшится при выходе из функции

    fmt.Printf("Worker %d starting\n", id)
    time.Sleep(time.Second) // Имитация продолжительной работы
    fmt.Printf("Worker %d done\n", id)
}

func main() {
    var wg sync.WaitGroup

    numWorkers := 3
    wg.Add(numWorkers) // Установка счётчика на количество работников

    for i := 1; i <= numWorkers; i++ {
        go worker(i, &wg) // Запуск каждого работника в отдельной горутине
    }

    wg.Wait() // Ожидание завершения всех горутин
    fmt.Println("All workers completed")
}
```

В этом примере мы создаём три горутины, каждая из которых выполняет функцию `worker`. С помощью `WaitGroup` мы синхронизируем завершение всех горутин, прежде чем печатаем сообщение "All workers completed".

`WaitGroup` является важным инструментом в арсенале для управления параллельным выполнением задач. Он обеспечивает элегантный способ дождаться завершения множества горутин, что особенно полезно в многопоточных и асинхронных приложениях.

April 14, 2024, easyoffer