Maison  >  Article  >  développement back-end  >  Pourquoi l'utilisation de sync.WaitGroup avec des fonctions externes entraîne-t-elle une impasse ?

Pourquoi l'utilisation de sync.WaitGroup avec des fonctions externes entraîne-t-elle une impasse ?

DDD
DDDoriginal
2024-11-06 19:43:02643parcourir

Why Does Using sync.WaitGroup with External Functions Lead to Deadlock?

Utilisation de sync.WaitGroup avec des fonctions externes

Dans un programme, vous pouvez rencontrer des problèmes lors de l'utilisation de sync.WaitGroup avec des fonctions définies en dehors de la fonction principale. Explorons cette situation.

Problème :

Considérez le code suivant :

<code class="go">package main

import (
    "fmt"
    "sync"
)

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() //deadlock here
}

// Print prints all numbers sent on the channel.
// The function returns when the channel is closed.
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>

Ici, vous visez que le programme imprime des nombres à partir de 1 à 11, mais il n'imprime parfois que 1 à 10.

Analyse des erreurs :

Vous transmettez une copie de sync.WaitGroup à la fonction d'impression, qui signifie qu'il n'appelle pas la méthode Done() sur le sync.WaitGroup que vous attendez dans la fonction principale.

Solution :

Pour résoudre ce problème , mettez à jour le code comme suit :

<code class="go">package main

import (
    "fmt"
    "sync"
)

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() //deadlock here
}

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>

Cela garantit que la fonction Print appelle la méthode Done() sur le même sync.WaitGroup que vous attendez dans la fonction principale.

Vous pouvez également restructurer votre code pour supprimer la dépendance à l'égard de sync.WaitGroup dans la fonction Imprimer :

<code class="go">package main

import (
    "fmt"
)

func main() {
    ch := make(chan int)

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

    for n := range ch { // reads from channel until it's closed
        fmt.Println(n)
    }
}</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