Полное руководство по WaitGroup в Golang: синхронизация стала проще

При параллельном программировании управление горутинами и обеспечение синхронного выполнения может оказаться непростой задачей. К счастью, Go предоставляет мощный примитив синхронизации под названием WaitGroup, который упрощает этот процесс. В этой статье мы рассмотрим различные методы использования WaitGroup в Golang с примерами кода, чтобы продемонстрировать его универсальность и эффективность.

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

Метод 1: базовое использование
Наиболее распространенный способ использования WaitGroup включает в себя три простых шага: добавление горутин в WaitGroup, выполнение горутин и ожидание их завершения. Вот пример:

package main
import (
    "fmt"
    "sync"
)
func main() {
    var wg sync.WaitGroup
    wg.Add(2) // Adding two goroutines
    go func() {
        defer wg.Done()
        // Perform some task
    }()
    go func() {
        defer wg.Done()
        // Perform some task
    }()
    wg.Wait() // Wait for all goroutines to complete
    fmt.Println("All goroutines have finished executing.")
}

Метод 2: ожидание с таймаутом
Иногда необходимо установить максимальное время ожидания завершения выполнения горутин. В таких случаях вы можете использовать комбинацию WaitGroup и каналов для реализации механизма тайм-аута. Вот пример:

package main
import (
    "fmt"
    "sync"
    "time"
)
func main() {
    var wg sync.WaitGroup
    wg.Add(1) // Adding a goroutine
    go func() {
        defer wg.Done()
        // Perform some task
    }()
    timeout := 3 * time.Second // Set timeout duration
    done := make(chan bool)
    go func() {
        wg.Wait() // Wait for all goroutines to complete
        done <- true
    }()
    select {
    case <-done:
        fmt.Println("All goroutines have finished executing.")
    case <-time.After(timeout):
        fmt.Println("Timeout occurred. Some goroutines did not finish.")
    }
}

Метод 3: динамическое количество горутин
В некоторых сценариях количество ожидающих горутин заранее неизвестно. WaitGroup обеспечивает гибкость в обработке таких ситуаций. Вот пример:

package main
import (
    "fmt"
    "sync"
)
func main() {
    var wg sync.WaitGroup
    tasks := []string{"task1", "task2", "task3"}
    for _, task := range tasks {
        wg.Add(1) // Adding a goroutine
        go func(task string) {
            defer wg.Done()
            // Perform task specific operations
            fmt.Println("Finished executing", task)
        }(task)
    }
    wg.Wait() // Wait for all goroutines to complete
    fmt.Println("All goroutines have finished executing.")
}

WaitGroup в Golang — мощный инструмент для координации горутин и обеспечения синхронного выполнения. Понимая его использование и изучая различные методы, вы сможете эффективно управлять параллелизмом в своих программах Go. Поэкспериментируйте с этими методами и воспользуйтесь гибкостью, которую предлагает WaitGroup, для создания эффективных и масштабируемых приложений.

Не забудьте импортировать пакет «sync», чтобы эффективно использовать WaitGroup в своем коде. Начните использовать WaitGroup сегодня и раскройте весь потенциал параллельного программирования в Golang!