Home >Backend Development >Golang >How to Select on a Buffered Send and Unbuffered Receive Channel Simultaneously in Go?
In Go, it is possible to perform non-blocking I/O operations on channels using the select statement. However, a common question arises when dealing with a buffered send channel (chan<-) and an unbuffered receive channel (<-chan): how can you select on both channels simultaneously, prioritizing the receive channel if it has data and the send channel if it has capacity?
One common approach is to check the length or capacity of the channels before sending or receiving. However, this is not reliable because the channel's state can change between the check and the subsequent operation:
<code class="go">if len(r) > 0 { // Optionally execute other code r <- v // May block if another goroutine received from r in the meantime }</p> <h3>The Solution: Default Case with Time Delay</h3> <p>To resolve this issue, you can use a select statement with a default case that includes a short time delay. This prevents excessive CPU usage while allowing you to retry the operation if both channels are not ready:</p> <pre class="brush:php;toolbar:false"><code class="go">s := make(chan<- int, 5) r := make(<-chan int) for { v := valueToSend() select { case s <- v: fmt.Println("Sent value:", v) case vr := <-r: fmt.Println("Received:", vr) default: // If none are ready, delay execution time.Sleep(time.Millisecond * 1) } }</code>
By adding the default case, the program will only block for a short period if both channels are not ready, allowing the CPU resources to be released while it waits for a channel to become available.
The above is the detailed content of How to Select on a Buffered Send and Unbuffered Receive Channel Simultaneously in Go?. For more information, please follow other related articles on the PHP Chinese website!