Golang timeout is not executed with channels

血红的双手。 提交于 2019-12-17 16:53:18

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!