How do I check whether a channel has a value for me to read?
I don't want to block when reading a channel. I want to see whether it has a value. If it does have one, I'll read it. If it doesn't have one (yet), I'll do something else and check back again later.
@Tom You can actually test if len(ch) == cap(ch) { ... } where len(ch) is the number of items in the channel and cap(ch) is the capacity.
Even though we can't send data to a closed channel, we can still read data from a closed channel. Consider the code shown below. package main import "fmt" func main() { ch := make(chan int, 3) ch <- 2 ch <- 3 close(ch) <-ch fmt. Println("Channel closed!") }
When we send data into the channel using a GoRoutine, it will be blocked until the data is consumed by another GoRoutine. When we receive data from channel using a GoRoutine, it will be blocked until the data is available in the channel.
By default, a channel buffer size is 0 also called as unbuffered channel.
The only non-blocking operation I know of to read from a channel is inside a select block having a default case :
select { case x, ok := <-ch: if ok { fmt.Printf("Value %d was read.\n", x) } else { fmt.Println("Channel closed!") } default: fmt.Println("No value ready, moving on.") }
Please try the non-blocking here
Note about previous answers: the receive operator itself is now a blocking operation, as of Go 1.0.3 . The spec has been modified. Please try the blocking here (deadlock)
If you're doing this often then it's probably not a great design and you might be better off spawning another goroutine to do whatever work you're planning to do when there isn't anything to read from the channel. The synchronous/blocking nature of Go's channels make code easier to read and reason about while the scheduler and cheap goroutines means that async calls are unnecessary since waiting goroutines take up very little resources.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With