问题
I am using goroutines/channels. Here is my code. Why is the timeout case not getting executed?
func main() {
c1 := make(chan int, 1)
go func() {
for {
time.Sleep(1500 * time.Millisecond)
c1 <- 10
}
}()
go func() {
for {
select {
case i := <-c1:
fmt.Println(i)
case <-time.After(2000 * time.Millisecond):
fmt.Println("TIMEOUT") // <-- Not Executed
}
}
}()
fmt.Scanln()
}
回答1:
Your timeout doesn't happen, because one of your goroutine sends a value on your c1
channel in every 1.5 seconds (or so) repeatedly, and your timeout would only happen if there is no value to be received from c1
for 2 seconds.
Once a value is received from c1
, in the next iteration executing select
again a new time.After()
call will be made which which returns a new channel on which a value will only be sent after another 2 seconds. The timeout channel from the previous select
execution is discarded and is not used anymore.
To receive the timeout after 2 seconds, create the timeout channel only once, e.g.:
timeout := time.After(2000 * time.Millisecond)
for {
select {
case i := <-c1:
fmt.Println(i)
case <-timeout:
fmt.Println("TIMEOUT") // Will get executed after 2 sec
}
}
Output:
10
TIMEOUT
10
10
10
...
来源:https://stackoverflow.com/questions/34894927/golang-timeout-is-not-executed-with-channels