Как оповестить пачку горутин о завершении работы?

В Go существует несколько способов оповестить пачку горутин о завершении работы. Рассмотрим два наиболее распространенных подхода: использование каналов и синхронизацию с помощью WaitGroup.

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

Пример кода с использованием каналов:

package main

import (
    "fmt"
    "sync"
)

func worker(id int, done chan bool) {
    // Выполнить работу
    fmt.Printf("Горутина %d завершила работуn", id)
    done <- true
}

func main() {
    numWorkers := 5 // Количество горутин

    done := make(chan bool) // Канал для оповещения о завершении работы горутин

    // Запуск горутин
    for i := 1; i <= numWorkers; i++ {
        go worker(i, done)
    }

    // Ожидание завершения работы всех горутин
    for i := 1; i <= numWorkers; i++ {
        <-done
    }

    fmt.Println("Все горутины завершили работу")
}

Второй способ основан на использовании синхронизации с помощью WaitGroup. WaitGroup предоставляет методы для ожидания завершения работы горутин. Вызовите метод Add() для установки количества ожидаемых горутин. Затем каждая горутина вызывает метод Done() для сигнализации о завершении работы. Наконец, вызовите метод Wait() для блокировки главной горутины, пока все ожидаемые горутины не вызовут Done().

Пример кода с использованием WaitGroup:

package main

import (
    "fmt"
    "sync"
)

func worker(id int, wg *sync.WaitGroup) {
    // Выполнить работу
    fmt.Printf("Горутина %d завершила работуn", id)
    wg.Done()
}

func main() {
    numWorkers := 5 // Количество горутин

    var wg sync.WaitGroup

    // Установка количества ожидаемых горутин
    wg.Add(numWorkers)

    // Запуск горутин
    for i := 1; i <= numWorkers; i++ {
        go worker(i, &wg)
    }

    // Ожидание завершения работы всех горутин
    wg.Wait()

    fmt.Println("Все горутины завершили работу")
}

Оба способа являются эффективными и надежными для оповещения о завершении работы группы горутин. Выбор конкретного метода зависит от ваших потребностей и предпочтений.