Erreur de blocage dans la concurrence : "lancer : tous les Goroutines sont endormis"
Lorsque vous travaillez avec la concurrence dans Go, un blocage peut se produire si tous les goroutines s'attendent pour effectuer une action. Une erreur courante associée à ce problème est « lancer : toutes les goroutines sont endormies - impasse ! »
Comprendre le problème
Considérez le programme Go suivant :
package main import ( "fmt" ) func total(ch chan int) { res := 0 for iter := range ch { res += iter } ch <- res } func main() { ch := make(chan int) go total(ch) ch <- 1 ch <- 2 ch <- 3 fmt.Println("Total is ", <-ch) }
Lors de l'exécution de ce programme, nous rencontrons l'erreur "throw : all goroutines are sleep - deadlock !" La raison en est que la boucle de plage dans la fonction total ne se terminera jamais car nous ne fermons jamais le canal ch. En conséquence, la goroutine en attente de recevoir le résultat dans la fonction principale ne le recevra jamais.
Résoudre l'impasse
Pour sortir de cette impasse, nous devons fermer le canal ch pour indiquer qu’aucune autre valeur ne sera envoyée. De plus, nous pouvons utiliser un canal distinct pour renvoyer le résultat, empêchant ainsi un envoi et une réception directs sur le même canal.
Le programme révisé ci-dessous résout ces problèmes :
package main import ( "fmt" ) func total(in chan int, out chan int) { res := 0 for iter := range in { res += iter } out <- res // sends back the result } func main() { ch := make(chan int) rch := make(chan int) go total(ch, rch) ch <- 1 ch <- 2 ch <- 3 close(ch) // this will end the loop in the total function result := <-rch // waits for total to give the result fmt.Println("Total is ", result) }
En terminant le canal ch et en utilisant un canal rch séparé pour le résultat, nous éliminons le blocage et permettons au programme de s'exécuter correctement.
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!