Résoudre l'impasse des Goroutines dans la concurrence Go
Dans les programmes Go simultanés, des blocages peuvent se produire lorsque les goroutines s'attendent indéfiniment les unes les autres pour libérer des ressources. Pour résoudre de tels blocages, considérons l'exemple suivant :
<code class="go">// Create a channel for communication between goroutines. ch := make(chan int) // Start producer goroutines that send values to the channel. go producer(ch, 100*time.Millisecond, 2) go producer(ch, 200*time.Millisecond, 5) // Indefinite loop to continuously receive values from the channel. for { fmt.Println(<-ch) }</code>
Ce code entraîne une erreur de blocage : "erreur fatale : toutes les goroutines sont endormies - blocage !" Cela se produit parce que les producteurs ont une durée de vie limitée, arrêtant finalement la transmission, tandis que le consommateur attend sans fin de nouvelles valeurs. Pour éviter cette impasse, deux stratégies principales peuvent être employées :
1. Résiliation de la chaîne :
Étant donné que les chaînes ne peuvent être fermées qu'une seule fois, il est essentiel que les producteurs signalent la résiliation au consommateur. Un coordinateur peut surveiller l'achèvement des producteurs et fermer la chaîne en conséquence.
2. Synchronisation coordonnée :
À l'aide d'une primitive de synchronisation telle que sync.WaitGroup, les producteurs peuvent avertir le coordinateur lorsqu'ils ont terminé, et celui-ci peut fermer la chaîne une fois que tous les producteurs ont terminé.
Code mis à jour à l'aide de la synchronisation :
<code class="go">import ( "fmt" "sync" "time" ) func producer(ch chan int, d time.Duration, num int, wg *sync.WaitGroup) { defer wg.Done() for i := 0; i < num; i++ { ch <- i time.Sleep(d) } } func main() { // Create a WaitGroup for coordinating producer completion. wg := &sync.WaitGroup{} // Initialize the channel for communication between goroutines. ch := make(chan int) // Start producer goroutines. wg.Add(2) go producer(ch, 100*time.Millisecond, 2, wg) go producer(ch, 200*time.Millisecond, 5, wg) // Assign a goroutine to close the channel when all producers have finished. go func() { wg.Wait() close(ch) }() // Iterate over values from the channel until it's closed. for v := range ch { fmt.Println(v) } }</code>
Conclusion :
En implémentant la terminaison de canal ou la synchronisation coordonnée, les développeurs peuvent efficacement éviter les blocages des goroutines et assurer une bonne coordination dans les programmes Go simultanés.
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!