Priority in Go Select Statement
When working with multiple channels using Go's select statement, the order in which channels are handled is not guaranteed. To prioritize one channel over another, a workaround is available.
Problem Statement
In the code snippet below, the goal is to ensure that all values in the out channel are processed before the exit channel:
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") }
However, using the select statement doesn't provide priority for one channel over the other.
Solution: Native Language Support
Go natively supports prioritizing channels in a select statement by restricting the visibility of the "quit" channel to only the producer. When the producer decides to quit, it closes the channel. The consumer will only quit when the channel is empty and closed.
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) }
In this example, the quit channel is only visible to the producer function (produceEndlessly). The producer randomly decides to quit after a certain delay. The consumer function (main) iterates over the vals channel until it is closed and empty. By prioritizing the producer's "quit" message, all values in the vals channel are processed before the program exits.
The above is the detailed content of How Can I Prioritize Channels in Go's `select` Statement?. For more information, please follow other related articles on the PHP Chinese website!