Maison >développement back-end >Golang >Comment corriger les erreurs de blocage dans les canaux Go lors de l'utilisation de sync.WaitGroup ?
Dans cet article, nous analyserons les causes derrière le « blocage ! » erreur résultant d'une situation de blocage impliquant les canaux Go dans l'extrait de code suivant :
package main 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() }
Lors de l'exécution de ce code, nous rencontrons l'erreur suivante :
throw: all goroutines are asleep - deadlock!
Le blocage se produit parce que les structures, comme le sync.WaitGroup dans ce code, sont transmises par valeur et non par référence. Cela signifie que lorsque nous transmettons le WaitGroup à nos fonctions (push et pull), nous transmettons en fait une copie du WaitGroup au lieu de l'objet d'origine.
En conséquence, chaque fonction travaille sur sa propre copie. du WaitGroup, et lorsqu'ils appellent wg.Done(), ils décrémentent leurs propres copies. Cela ne met pas à jour le WaitGroup d'origine, ce qu'attend notre goroutine principale, conduisant ainsi à une impasse.
Pour résoudre ce problème, nous devons passer le pointeur au WaitGroup au lieu de la valeur. Cela garantira que les fonctions push et pull fonctionnent sur la même instance de WaitGroup et que leurs appels à wg.Done() affecteront l'objet d'origine.
Voici une version corrigée du code :
package main 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() }
En effectuant cette modification, nous transmettons désormais le pointeur vers le WaitGroup à nos fonctions, garantissant que les deux travaillent sur le même objet et mettent correctement à jour son état. Cela élimine la situation de blocage et permet à notre programme de s'exécuter sans aucune erreur.
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!