Priorité dans l'instruction Go Select : une compréhension révisée
Dans Go, l'instruction select est un outil polyvalent pour gérer plusieurs canaux simultanément. Cependant, par défaut, il fonctionne sans aucun ordre de priorité, ce qui peut conduire à des résultats inattendus. Cet article examine un scénario de solution de contournement courant et fournit une compréhension plus nuancée de la gestion des priorités dans Go.
Considérez l'extrait de code suivant :
func sender(out chan int, exit chan bool) { for i := 1; i <= 10; i++ { out <- i } exit <- true } func main(){ out := make(chan int, 10) exit := make(chan bool) go sender(out, exit) L: for { select { case i := <-out: fmt.Printf("Value: %d\n", i) case <-exit: fmt.Println("Exiting") break L } } fmt.Println("Did we get all 10? Most likely not") }
Dans cet exemple, nous souhaitons recevoir des valeurs de les canaux de sortie et de sortie et les gérer dans un ordre spécifique. Cependant, l'instruction select permet de gérer les deux canaux simultanément, ce qui permet de recevoir le signal de sortie avant que toutes les valeurs de out ne soient reçues.
Pour résoudre ce problème, une solution de contournement couramment proposée consiste à utiliser des cas par défaut pour canaux non gérés. Cependant, l'instruction select de Go prend en charge la gestion des priorités de manière native, éliminant ainsi le besoin de solutions de contournement.
La solution native
La clé réside dans l'isolement du canal de sortie vers le producteur. Lorsque le producteur souhaite signaler la fin, il ferme le canal de sortie. Par conséquent, ce n'est que lorsque le canal de sortie est vide et fermé que le consommateur recevra le signal de sortie. Ceci est réalisé en s'étendant sur le canal de sortie :
func main() { vals, quit := make(chan int, 10), make(chan bool) go produceEndlessly(vals, quit) go quitRandomly(quit) for x := range vals { fmt.Println(x) processed++ time.Sleep(time.Duration(rand.Int63n(5e8))) } fmt.Println("Produced:", produced) fmt.Println("Processed:", processed) }
Dans cet exemple modifié, la fonction ProduceEndlessly pousse continuellement les valeurs dans le canal vals jusqu'à ce qu'elle reçoive un signal pour quitter. La fonction quitRandomly envoie le signal après un délai aléatoire.
En parcourant le canal vals, le consommateur attend que toutes les valeurs aient été reçues et que le canal soit fermé avant de procéder au traitement du signal de sortie. Cela garantit que toutes les valeurs du canal vals sont traitées avant la fin du programme.
Conclusion
L'instruction select de Go fournit une solution robuste pour gérer plusieurs canaux simultanément. En comprenant les capacités natives de gestion des priorités de Go, il devient possible de mettre en œuvre des mécanismes de sélection basés sur les priorités sans avoir besoin de solutions de contournement. Cette approche simplifie le code et améliore la clarté et l'efficacité de la gestion des canaux dans les programmes Go.
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!