Choose by time.
package main
import "time"
func main() {
chan_never_used := make(chan int, 10)
c := make(chan int, 10)
for {
select {
case <-time.After(time.Second):
c <- 0
case c <- <-chan_never_used:
}
println(<-c)
}
}
https://play.golang.org/p/7hZMdITecg
The above code results in fatal error: all goroutines are asleep - deadlock!
.
But if I change one line:
package main
import "time"
func main() {
chan_never_used := make(chan int, 10)
c := make(chan int, 10)
for {
select {
case <-time.After(time.Second):
c <- 0
case n := <-chan_never_used: // This line changed
c <- n // Add this line
}
println(<-c)
}
}
Works well.
Why is the first version of the code deadlocked, and why would this change make the code work?
source to share
According to the standard, the select statement contains a bunch of Send or Receive report .
In this case, it is the send statement.
The send operator is defined as:
SendStmt = Channel "<-" Expression .
Channel = Expression .
Looking at your code:
case c <- <-chan_never_used:
Faction Channel
c
, faction Expression
<-chan_never_used
.
Thus, the semantics of select
the (potentially) non-blocking send operator does not apply, since it is an expression that blocks. And before applying Send Statement semantics, the Expression part must be fully evaluated.
source to share