Как мне реализовать подпрограммы в бесконечном цикле for; для{}, который повторяет попытку, когда группа ожидания завершена?

#go

#Вперед

Вопрос:

Мой сценарий заключается в том, что я хочу запустить несколько подпрограмм go, которые прослушивают сетевой трафик, если в одной из функций подпрограммы go есть ошибка, функция выполнит wg.done(), и этот цикл for должен ждать, пока другие подпрограммы go выполнят wg.done(), и через некоторое время, например, через десять минут ожидания, этот цикл for должен выполняться снова. Это что-то вроде логики повторных попыток. Может кто-нибудь помочь с этим. Спасибо. Ниже приведен код, который я придумал до сих пор.

 package main

import (
    "errors"
    "fmt"
    "sync"
)

func main() {

    var wg sync.WaitGroup
    for {
        wg.Add(1)
        go A(amp;wg)
        wg.Add(1)
        go B(amp;wg)

    }
    wg.Wait()

}

func A(wg *sync.WaitGroup) {

    fmt.Println("inside function A")

    err := errors.New("There is an error")
    if err != nil {
        wg.Done()
    }

}

func B(wg *sync.WaitGroup) {

    fmt.Println("Inside function B")

    err := errors.New("There is an error")
    if err != nil {
        wg.Done()
    }

}
  

Ответ №1:

Ваш wg.Wait() никогда не запускается, поскольку он находится за пределами бесконечного цикла.

Я предполагаю, что вы ищете что-то подобное?

 for {
    tC := time.After(10 * time.Minute) // start timer before workers
    
    wg.Add(1)
    go A(amp;wg)

    wg.Add(1)
    go B(amp;wg)

    wg.Wait() // waits for both A amp; B to complete - whether they succeed or not

    <-tC // wait for remainder of 10 minutes before retrying
}
  

Пример игровой площадки

Одно предостережение с вышеизложенным: если для выполнения A amp; B требуется больше 10 минут, таймер срабатывает и <-tC не будет ждать, что приводит к немедленному перезапуску цикла.


Наконец, если вы хотите гарантировать, что выполнение A или B не займет больше 10 минут, тогда ваши рабочие программы должны изучить возможность использования пакета context. Передавая контекст через, скажем context.WithTimeout(...) , вы можете гарантировать, что рабочий завершит работу, как только контекст отменится (т. Е. Время ожидания истекло).

Комментарии:

1. Это полезно. Спасибо.

2. @SaiBagam пожалуйста, примите ответ, если он соответствует вашим потребностям, и закройте вопрос. Спасибо!