Maison > développement back-end > Golang > 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
Libérer: 2024-11-06 19:43:02
original
718 Les gens l'ont consulté

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>
Copier après la connexion

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>
Copier après la connexion

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>
Copier après la connexion

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!

source:php.cn
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal