Maison > développement back-end > Golang > le corps du texte

Pourquoi la transmission de valeurs au lieu de pointeurs provoque-t-elle un blocage dans les canaux Go ?

Barbara Streisand
Libérer: 2024-10-28 21:44:02
original
296 Les gens l'ont consulté

Why Does Passing Values Instead of Pointers Cause Deadlock in Go Channels?

Erreur de blocage dans le canal Go

Dans Go, les canaux fournissent un moyen de communication entre les goroutines. Cependant, une mauvaise utilisation des canaux peut conduire à des blocages, où les goroutines sont bloquées indéfiniment.

Une cause fréquente de blocages avec les canaux est la transmission de types de valeur au lieu de pointeurs dans les fonctions goroutine. En effet, Go transmet les types de valeur par valeur, ce qui signifie qu'une copie de la valeur est créée.

Considérez cet exemple :

<code class="go">import (
    "fmt"
    "sync"
)

func push(c chan int, wg sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    wg.Done()
}

func pull(c chan int, wg sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        result, ok := <-c
        fmt.Println(result, ok)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    c := make(chan int)

    go push(c, wg)
    go pull(c, wg)

    wg.Wait()
}</code>
Copier après la connexion

L'exécution du programme entraîne une erreur de blocage :

    0 true
    1 true
    2 true
    3 true
    4 true
    throw: all goroutines are asleep - deadlock!
Copier après la connexion

Le blocage se produit car le WaitGroup est transmis aux fonctions push et pull en tant que valeur. Lorsque le WaitGroup est mis à jour dans l'un des goroutines, les modifications ne sont pas reflétées dans l'autre goroutine car il a une copie de la valeur.

Pour résoudre le blocage, nous devons passer le WaitGroup comme pointeur, qui garantit que les deux goroutines fonctionnent sur la même instance du WaitGroup.

Voici la version corrigée du code :

<code class="go">import (
    "fmt"
    "sync"
)

func push(c chan int, wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        c <- i
    }
    wg.Done()
}

func pull(c chan int, wg *sync.WaitGroup) {
    for i := 0; i < 5; i++ {
        result, ok := <-c
        fmt.Println(result, ok)
    }
    wg.Done()
}

func main() {
    var wg sync.WaitGroup
    wg.Add(2)
    c := make(chan int)

    go push(c, &wg)
    go pull(c, &wg)

    wg.Wait()
}</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
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!