Тип sync.WaitGroup
Тип sync.WaitGroup предназначен для ожидания завершения
группы горутин. Он позволяет главной горутине дождаться,
пока все запущенные горутины завершат свою работу.
Основные методы: Add для увеличения счетчика,
Done для уменьшения счетчика и Wait
для блокировки до обнуления счетчика.
Синтаксис
var wg sync.WaitGroup
wg.Add(n)
wg.Done()
wg.Wait()
Пример
Давайте запустим три горутины и дождемся их завершения:
package 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")
}
Результат выполнения кода:
"Goroutine 1 finished"
"Goroutine 2 finished"
"Goroutine 3 finished"
"All goroutines finished"
Пример
Давайте используем WaitGroup для параллельной
обработки данных из слайса:
package 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)
}
Результат выполнения кода:
[2 4 6 8 10]
Пример
Давайте продемонстрируем правильное использование
WaitGroup с передачей указателя в функцию:
package 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")
}
Результат выполнения кода:
"Worker 3 done"
"Worker 1 done"
"Worker 2 done"
"All workers done"
Смотрите также
-
функцию
sync.WaitGroup.Add,
которая увеличивает счетчик ожидания -
функцию
sync.WaitGroup.Done,
которая уменьшает счетчик ожидания -
функцию
sync.WaitGroup.Wait,
которая блокирует выполнение до обнуления счетчика -
тип
sync.Mutex,
который используется для взаимного исключения