Home >Backend Development >Golang >Go Channels: Why Doesn't My Timeout in a `select` Statement Ever Trigger?

Go Channels: Why Doesn't My Timeout in a `select` Statement Ever Trigger?

DDD
DDDOriginal
2024-12-26 03:37:09404browse

Go Channels: Why Doesn't My Timeout in a `select` Statement Ever Trigger?

Go Channels: Why Timeouts Remain Unexecuted

Consider a scenario where goroutines and channels are employed like in the code snippet below. Why does the timeout scenario never materialize?

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()
}

Analysis

The timeout scenario does not occur because a goroutine continuously sends values to the c1 channel roughly every 1.5 seconds. The timeout would only become effective if no values were received from c1 for 2 seconds.

However, upon receiving a value from c1, a new time.After call is made in the subsequent select execution, generating a fresh channel where a value will only be issued after another 2 seconds. The timeout channel from the previous select execution is discarded, rendering it ineffective.

Solution

To address this issue, the timeout channel should be created only once, effectively:

timeout := time.After(2000 * time.Millisecond)
for {
    select {
    case i := <-c1:
        fmt.Println(i)
    case <-timeout:
        fmt.Println("TIMEOUT") // Will be printed after 2 seconds
    }
}

Output

The modified code subsequently prints:

10
TIMEOUT
10
10
10
...

Hence, the timeout scenario is now successfully executed after 2 seconds, mirroring the intended behavior.

The above is the detailed content of Go Channels: Why Doesn't My Timeout in a `select` Statement Ever Trigger?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn