Как дождаться выполнения нескольких горутин
1️⃣ Как кратко ответить
Для ожидания выполнения нескольких горутин в Go используется sync.WaitGroup. Он позволяет отслеживать количество активных горутин и блокировать выполнение основной программы до тех пор, пока все горутины не завершатся.
2️⃣ Подробное объяснение темы
В языке программирования Go горутины — это легковесные потоки, которые позволяют выполнять функции параллельно. Однако, когда вы запускаете несколько горутин, может возникнуть необходимость дождаться их завершения перед продолжением выполнения основной программы. Для этого в Go используется структура sync.WaitGroup.
Зачем это нужно
Когда вы запускаете несколько горутин, они выполняются асинхронно. Если основная программа завершится раньше, чем горутины, то они могут быть прерваны, и их работа не будет завершена. sync.WaitGroup позволяет синхронизировать выполнение, гарантируя, что основная программа дождется завершения всех горутин.
Как это работает
sync.WaitGroup предоставляет три основных метода:
Add(delta int): увеличивает счетчик горутин на указанное количество.Done(): уменьшает счетчик на единицу, сигнализируя о завершении одной горутины.Wait(): блокирует выполнение до тех пор, пока счетчик не станет равным нулю.
Пример использования
Рассмотрим пример, где мы запускаем несколько горутин и ждем их завершения:
package main
import (
"fmt"
"sync"
"time"
)
func worker(id int, wg *sync.WaitGroup) {
defer wg.Done() // Уменьшает счетчик на 1, когда горутина завершает выполнение
fmt.Printf("Worker %d starting\n", id)
time.Sleep(time.Second) // Симулирует работу, которая занимает 1 секунду
fmt.Printf("Worker %d done\n", id)
}
func main() {
var wg sync.WaitGroup // Создаем экземпляр WaitGroup
const numWorkers = 5
wg.Add(numWorkers) // Устанавливаем счетчик равным количеству горутин
for i := 1; i <= numWorkers; i++ {
go worker(i, &wg) // Запускаем горутину и передаем указатель на WaitGroup
}
wg.Wait() // Блокируем выполнение до тех пор, пока все горутины не вызовут Done()
fmt.Println("All workers done")
}
Пояснение к коду
-
Импортируем пакеты:
fmtдля вывода в консоль,syncдля использованияWaitGroup, иtimeдля симуляции задержки. -
Функция
worker: принимает идентификатор и указатель наWaitGroup.defer wg.Done(): гарантирует, что счетчик уменьшится на 1, когда функция завершится.fmt.Printf: выводит сообщение о начале и завершении работы.time.Sleep: симулирует выполнение задачи, задерживая выполнение на 1 секунду.
-
Функция
main:- Создает экземпляр
WaitGroup. - Устанавливает счетчик
WaitGroupравным количеству горутин с помощьюwg.Add(numWorkers). - Запускает
numWorkersгорутин, передавая каждой идентификатор и указатель наWaitGroup. wg.Wait(): блокирует выполнение основной программы до тех пор, пока все горутины не завершатся.
- Создает экземпляр
Этот механизм позволяет эффективно управлять параллельным выполнением задач в Go, обеспечивая корректное завершение всех горутин перед продолжением выполнения основной программы.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться