Détection des blocages dans la concurrence Go avec les groupes d'attente
Dans Go, la concurrence est souvent gérée à l'aide de canaux et de groupes d'attente pour orchestrer des goroutines. Cependant, il est essentiel de comprendre les pièges potentiels qui peuvent conduire à des blocages.
Description du problème
Considérez le code suivant qui tente d'utiliser des canaux et des groupes d'attente mis en mémoire tampon :
<code class="go">package main import ( "fmt" "sync" ) func main() { ch := make(chan []int, 4) var m []int var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { defer wg.Done() ch <- m // Send to channel return }() } wg.Wait() // Wait for all goroutines to complete for c := range ch { fmt.Printf("c is %v", c) // Iterate over channel } }</code>
Bien que le canal s'attende à se fermer automatiquement une fois sa capacité atteinte, ce code entraîne de manière inattendue une erreur de blocage.
Solution
Il existe deux problèmes clés menant à l'impasse :
Pour sortir de l'impasse, deux solutions sont :
Solution 1 : Agrandissement de la capacité du canal et fermeture explicite
<code class="go">ch := make(chan []int, 5) // Increase channel capacity ... wg.Wait() close(ch) // Close the channel to stop range loop</code>
Cela garantit qu'il y a suffisamment d'espace dans le canal et le ferme explicitement, permettant à la boucle de plage de se terminer.
Solution 2 : Signal Done Condition dans Goroutine
<code class="go">func main() { ch := make(chan []int, 4) var m []int var wg sync.WaitGroup for i := 0; i < 5; i++ { wg.Add(1) go func() { ch <- m wg.Done() // Signal completion within goroutine return }() } go func() { for c := range ch { fmt.Printf("c is %v\n", c) wg.Done() //Decrement count for each iteration } }() wg.Wait() }</code>
Dans cette solution, chaque goroutine signale son achèvement en appelant wg.Done() dans la goroutine elle-même. Le groupe d'attente est également décrémenté dans la boucle de plage pour chaque itération, garantissant que wg.Wait() se termine finalement et que le programme se termine.
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!