Priorité dans l'instruction Go Select
Lorsque vous travaillez avec plusieurs canaux à l'aide de l'instruction select de Go, l'ordre dans lequel les canaux sont traités n'est pas garanti. Pour donner la priorité à un canal par rapport à un autre, une solution de contournement est disponible.
Énoncé du problème
Dans l'extrait de code ci-dessous, l'objectif est de garantir que toutes les valeurs du canal de sortie sont traités avant le canal de sortie :
package main import "fmt" 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") }
Cependant, l'utilisation de l'instruction select ne donne pas la priorité à un canal sur le autre.
Solution : prise en charge de la langue native
Go prend en charge nativement la priorisation des chaînes dans une instruction select en limitant la visibilité de la chaîne « quitter » au seul producteur. Lorsque le producteur décide de démissionner, il ferme la chaîne. Le consommateur ne quittera que lorsque le canal sera vide et fermé.
package main import ( "fmt" "math/rand" "time" ) var ( produced = 0 processed = 0 ) func produceEndlessly(out chan int, quit chan bool) { defer close(out) for { select { case <-quit: fmt.Println("RECV QUIT") return default: out <- rand.Int() time.Sleep(time.Duration(rand.Int63n(5e6))) produced++ } } } func quitRandomly(quit chan bool) { d := time.Duration(rand.Int63n(5e9)) fmt.Println("SLEEP", d) time.Sleep(d) fmt.Println("SEND QUIT") quit <- true } 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, le canal de sortie n'est visible que par la fonction producteur (produceEndlessly). Le producteur décide d'arrêter, au hasard, après un certain délai. La fonction consommateur (principale) parcourt le canal vals jusqu'à ce qu'il soit fermé et vide. En donnant la priorité au message « quitter » du producteur, toutes les valeurs du canal vals sont traitées avant la fin du programme.
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!