Maison >développement back-end >Golang >Pourquoi mon Go WaitGroup provoque-t-il un message « Tous les Goroutines sont endormis – impasse ! » Erreur?

Pourquoi mon Go WaitGroup provoque-t-il un message « Tous les Goroutines sont endormis – impasse ! » Erreur?

Barbara Streisand
Barbara Streisandoriginal
2024-12-25 19:14:17762parcourir

Why Does My Go WaitGroup Cause a

WaitGroup Deadlock : Comprendre « Tous les goroutines sont endormis - Deadlock ! »

Lorsque vous essayez de coordonner des goroutines à l'aide d'un WaitGroup, il est possible de rencontrer l'erreur "erreur fatale : toutes les goroutines sont endormies - impasse !". Cela se produit lorsque les goroutines responsables de la décrémentation du compteur du WaitGroup finissent par dormir par inadvertance.

Le problème :

Le code Go suivant illustre comment cette erreur peut survenir :

package main

import (
    "fmt"
    "sync"
)

func main() {
    var wg sync.WaitGroup
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            fmt.Println("Hello", i)
        }()
    }
    wg.Wait()
}

Lors de l'exécution, ce code devrait afficher "Bonjour" pour chaque goroutine. Cependant, au lieu de cela, le programme se termine avec la redoutable erreur « deadlock ».

La raison :

Le problème réside dans la manière dont le WaitGroup est transmis aux goroutines. Go fait une copie de la valeur lorsqu'elle est transmise à la fonction anonyme. Ainsi, chaque goroutine fonctionne sur une copie distincte du WaitGroup, dont aucun n'a son compteur décrémenté, ce qui entraîne une veille perpétuelle des goroutines.

La solution :

Pour résoudre le blocage, un pointeur vers le WaitGroup doit être transmis à la place du WaitGroup lui-même. Ainsi, toutes les goroutines référenceront le même WaitGroup, leur permettant de décrémenter correctement son compteur :

package main

import (
    "fmt"
    "sync"
)

func main() {
    wg := &sync.WaitGroup{}
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go func() {
            defer wg.Done()
            fmt.Println("Hello", i)
        }()
    }
    wg.Wait()
}

En passant un pointeur, les goroutines partagent le même objet WaitGroup et peuvent réussir à coordonner leur exécution. Cette version du code imprimera correctement "Bonjour" pour chaque goroutine sans déclencher l'impasse.

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