Maison >développement back-end >Golang >Comment implémenter une attente chronométrée pour WaitGroup.Wait() dans Go ?

Comment implémenter une attente chronométrée pour WaitGroup.Wait() dans Go ?

Linda Hamilton
Linda Hamiltonoriginal
2024-12-03 21:00:19899parcourir

How to Implement a Timed Wait for WaitGroup.Wait() in Go?

Attente temporisée pour WaitGroup.Wait()

Dans Go, le type WaitGroup est utilisé pour synchroniser plusieurs goroutines jusqu'à ce que tous aient terminé leurs tâches . La méthode WaitGroup.Wait() se bloque jusqu'à ce que tous les membres du groupe aient signalé leur achèvement ou que le contexte soit annulé.

Cependant, il est parfois souhaitable d'imposer un timeout à l'opération d'attente WaitGroup, pour empêcher le planificateur d'attendre indéfiniment un travailleur errant. Cela ouvre des questions philosophiques sur la fiabilité et la récupérabilité du système en présence de telles erreurs, mais cette discussion dépasse le cadre de cette question.

Solution

La solution fournie utilise un canal et une instruction select pour obtenir la fonctionnalité de délai d'attente :

c := make(chan struct{})
go func() {
    defer wg.Done()
    // Do the work
    c <- struct{}{}
}()
select {
case <-c:
    // Work completed
case <-time.After(timeout):
    // Timed out
}

Cette solution est efficace, mais elle peut sembler trop alambiqué. Les conseils suivants peuvent l'améliorer :

  • Envisagez d'utiliser la fermeture du canal pour signaler l'achèvement au lieu d'envoyer une valeur sur le canal. La lecture à partir d'un canal fermé s'effectue toujours immédiatement.
  • Utilisez l'instruction defer pour signaler la fin. Il s'exécute même si une fonction se termine brusquement.
  • S'il n'y a qu'un seul travail à attendre, omettez le WaitGroup et utilisez directement un canal.
  • Pour les délais d'attente, spécifiez directement la durée, par exemple : timeout := time.Second (ou 2 * time.Second pour un délai de 2 secondes timeout).

Fonction d'assistance

Pour simplifier le processus, une fonction d'assistance peut être créée pour encapsuler la logique de délai d'attente :

func waitTimeout(wg *sync.WaitGroup, timeout time.Duration) bool {
    c := make(chan struct{})
    go func() {
        defer close(c)
        wg.Wait()
    }()
    select {
    case <-c:
        return false // Completed normally
    case <-time.After(timeout):
        return true // Timed out
    }
}

Cette fonction enveloppe la fonctionnalité de délai d'attente et la rend facile à utiliser :

if waitTimeout(&wg, time.Second) {
    fmt.Println("Timed out waiting for wait group")
} else {
    fmt.Println("Wait group finished")
}

Cette approche fournit une approche plus propre et un moyen plus pratique de gérer les délais d'attente pour les opérations WaitGroup.Wait().

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn