Maison >développement back-end >Golang >Comment résoudre les blocages dans Go lorsque tous les Goroutines sont endormis ?
Impasse dans Go : "Tous les goroutines sont endormis"
Lorsque vous travaillez avec des goroutines, il est crucial de gérer efficacement les opérations des canaux pour éviter les blocages. Cela se produit lorsque toutes les goroutines sont bloquées indéfiniment, conduisant à une situation de blocage.
Comprendre le code
Examinons le code fourni :
package main import ( "fmt" "sync" "time" ) type Item struct { name string } type Truck struct { Cargo []Item name string } func UnloadTrucks(c chan Truck) { for t := range c { fmt.Printf("%s has %d items in cargo: %s\n", t.name, len(t.Cargo), t.Cargo[0].name) } } func main() { trucks := make([]Truck, 2) ch := make(chan Truck) for i, _ := range trucks { trucks[i].name = fmt.Sprintf("Truck %d", i+1) fmt.Printf("Building %s\n", trucks[i].name) } for t := range trucks { go func(tr Truck) { itm := Item{} itm.name = "Groceries" fmt.Printf("Loading %s\n", tr.name) tr.Cargo = append(tr.Cargo, itm) ch <- tr }(trucks[t]) } time.Sleep(50 * time.Millisecond) fmt.Println("Unloading Trucks") UnloadTrucks(ch) fmt.Println("Done") }
Ce code crée un canal ch de type Truck et lance deux goroutines pour simuler le chargement de camions de produits d'épicerie et leur envoi vers le canal. Il appelle ensuite UnloadTrucks pour récupérer et imprimer le contenu des camions.
Cause du blocage
Le problème réside dans l'absence de mécanisme pour fermer le canal ch. Lorsque tous les goroutines ont envoyé leurs camions vers le canal, il n'y a aucun signal pour terminer la boucle dans UnloadTrucks. Cela signifie que ch continue d'écouter les valeurs qui n'arrivent jamais, ce qui entraîne un blocage.
Solution
Pour résoudre le blocage, nous devons fermer explicitement le canal ch lorsque les goroutines de chargement sont terminées. Nous pouvons utiliser un sync.WaitGroup pour compter les goroutines en cours d'exécution et fermer le canal lorsque tous ont terminé :
var wg sync.WaitGroup go func() { wg.Wait() close(ch) }() UnloadTrucks(ch)
Cette modification garantit que UnloadTrucks se terminera une fois que toutes les goroutines auront fini de charger les camions. La fonction Wait se bloque jusqu'à ce que le compteur WaitGroup atteigne zéro, indiquant que toutes les goroutines ont terminé leur travail. La fermeture du canal signale à UnloadTrucks qu'il n'y a plus de camions à recevoir, lui permettant ainsi de sortir gracieusement de la boucle.
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!