Go select Statement Priority Workaround
Consider the following scenario: you want a Go routine to monitor two channels, remaining blocked when both channels are empty. However, when both channels contain data, you prioritize draining one channel before addressing the other.
Original Problem:
In the provided code sample, you have an out channel and an exit channel. You want all out values to be processed before handling the exit signal. However, the select statement does not have a built-in priority mechanism.
Workaround Solution:
Go natively supports this prioritization, eliminating the need for a workaround. The solution involves making the quit channel accessible only to the producer. When the producer finishes, it closes the quit channel. The consumer continues reading from the out channel until it's empty and the quit channel is closed.
Here's how the modified code looks:
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 main() { vals, quit := make(chan int, 10), make(chan bool) go produceEndlessly(vals, quit) for x := range vals { fmt.Println(x) processed++ time.Sleep(time.Duration(rand.Int63n(5e8))) } fmt.Println("Produced:", produced) fmt.Println("Processed:", processed) }
Explanation:
In the modified code, only the producer goroutine has access to the quit channel. When the producer finishes, it closes the quit channel. The consumer goroutine continues reading from the out channel until it's empty and the quit channel is closed. This ensures that all out values are processed before the consumer exits.
The above is the detailed content of How Can I Prioritize Channel Reads in Go's `select` Statement?. For more information, please follow other related articles on the PHP Chinese website!