Тип sync.WaitGroup

Тип sync.WaitGroup предназначен для ожидания завершения группы горутин. Он позволяет главной горутине дождаться, пока все запущенные горутины завершат свою работу. Основные методы: Add для увеличения счетчика, Done для уменьшения счетчика и Wait для блокировки до обнуления счетчика.

Синтаксис

govar wg sync.WaitGroup
wg.Add(n)
wg.Done()
wg.Wait()

Пример

Давайте запустим три горутины и дождемся их завершения:

gopackage main

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

func main() {
  var wg sync.WaitGroup

  for i := 1; i <= 3; i++ {
    wg.Add(1)
    go func(id int) {
      defer wg.Done()
      time.Sleep(time.Second)
      fmt.Printf("Goroutine %d finished\n", id)
    }(i)
  }

  wg.Wait()
  fmt.Println("All goroutines finished")
}

Результат выполнения кода:

go"Goroutine 1 finished"
"Goroutine 2 finished"
"Goroutine 3 finished"
"All goroutines finished"

Пример

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

gopackage main

import (
  "fmt"
  "sync"
)

func main() {
  var wg sync.WaitGroup
  data := []int{1, 2, 3, 4, 5}
  results := make([]int, len(data))

  for i, val := range data {
    wg.Add(1)
    go func(idx, v int) {
      defer wg.Done()
      results[idx] = v * 2
    }(i, val)
  }

  wg.Wait()
  fmt.Println(results)
}

Результат выполнения кода:

go[2 4 6 8 10]

Пример

Давайте продемонстрируем правильное использование WaitGroup с передачей указателя в функцию:

gopackage main

import (
  "fmt"
  "sync"
)

func worker(wg *sync.WaitGroup, id int) {
  defer wg.Done()
  fmt.Printf("Worker %d done\n", id)
}

func main() {
  var wg sync.WaitGroup

  for i := 1; i <= 3; i++ {
    wg.Add(1)
    go worker(&wg, i)
  }

  wg.Wait()
  fmt.Println("All workers done")
}

Результат выполнения кода:

go"Worker 3 done"
"Worker 1 done"
"Worker 2 done"
"All workers done"

Смотрите также

  • функцию sync.WaitGroup.Add,
    которая увеличивает счетчик ожидания
  • функцию sync.WaitGroup.Done,
    которая уменьшает счетчик ожидания
  • функцию sync.WaitGroup.Wait,
    которая блокирует выполнение до обнуления счетчика
  • тип sync.Mutex,
    который используется для взаимного исключения