Maison  >  Article  >  développement back-end  >  Pourquoi l'utilisation d'une copie de Sync.WaitGroup dans une fonction externe entraîne-t-elle une sortie manquante dans une goroutine ?

Pourquoi l'utilisation d'une copie de Sync.WaitGroup dans une fonction externe entraîne-t-elle une sortie manquante dans une goroutine ?

Mary-Kate Olsen
Mary-Kate Olsenoriginal
2024-11-06 14:00:03492parcourir

Why does using a copy of Sync.WaitGroup in an external function lead to missing output in a goroutine?

Utilisation de Sync.WaitGroup avec des fonctions externes

Dans le code fourni, l'intention est que la goroutine principale imprime les nombres de 1 à 11 en utilisant un canal et un groupe d'attente. Cependant, il saute parfois le numéro 11, ce qui entraîne une sortie incomplète.

Le problème provient d'une connexion incorrecte de sync.WaitGroup à la fonction externe, Print. En transmettant une copie de WaitGroup à la fonction, elle ne peut pas effectuer l'appel Done() nécessaire sur le groupe d'attente d'origine attendu par la goroutine principale.

Meilleure solution :

La solution recommandée consiste à modifier le code comme suit :

<code class="go">func main() {
    ch := make(chan int)

    var wg sync.WaitGroup
    wg.Add(2)

    go Print(ch, &wg)

    go func() {
        for i := 1; i <= 11; i++ {
            ch <- i
        }
        close(ch)
        defer wg.Done()
    }()

    wg.Wait()
}

func Print(ch <-chan int, wg *sync.WaitGroup) {
    for n := range ch { // reads from channel until it's closed
        fmt.Println(n)
    }
    defer wg.Done()
}</code>

Dans ce correctif, la fonction Print reçoit un pointeur vers le groupe d'attente, garantissant que sa méthode Done() est appelée dans le fonction, permettant ainsi à la goroutine principale de procéder correctement.

Solution alternative :

Alternativement, on peut éliminer le besoin de WaitGroup dans la fonction d'impression en fermant directement le canal après avoir envoyé tous les numéros :

<code class="go">func Print(ch <-chan int) {
    for n := range ch { // reads from channel until it's closed
        fmt.Println(n)
    }
}</code>

Dans ce cas, la goroutine principale doit plutôt attendre la fermeture de la chaîne :

<code class="go">wg.Wait()
close(ch)</code>

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