【问题标题】:Why doesn't this Golang code to select among multiple time.After channels work?为什么这个 Golang 代码不能在多个 time.After 通道中进行选择?
【发布时间】:2016-05-04 08:42:18
【问题描述】:

为什么这个 Golang 代码不能在多个时间中进行选择。在频道工作后?

见下面的代码。永远不会发出“超时”消息。为什么?

package main

import (
    "fmt"
    "time"
)

func main() {
    count := 0
    for {
        select {
        case <-time.After(1 * time.Second):
            count++
            fmt.Printf("tick %d\n", count)
            if count >= 5 {
                fmt.Printf("ugh\n")
                return
            }
        case <-time.After(3 * time.Second):
            fmt.Printf("timeout\n")
            return
        }
    }
}

在 Playground 上运行它:http://play.golang.org/p/1gku-CWVAh

输出:

tick 1
tick 2
tick 3
tick 4
tick 5
ugh

【问题讨论】:

标签: time go timeout channel


【解决方案1】:

即使@Ainar-G 已经提供了答案,另一种可能是使用time.Tick(1e9) 每秒生成一个时间刻度,然后在指定时间段后监听timeAfterchannel。

package main

import (
    "fmt"
    "time"
)

func main() {
    count := 0
    timeTick := time.Tick(1 * time.Second)
    timeAfter := time.After(5 * time.Second)

    for {
        select {
        case <-timeTick:
            count++
            fmt.Printf("tick %d\n", count)
            if count >= 5 {
                fmt.Printf("ugh\n")
                return
            }
        case <-timeAfter:
            fmt.Printf("timeout\n")
            return
        }
    }
}

【讨论】:

    【解决方案2】:

    因为time.After 是一个函数,所以每次迭代都会返回一个新通道。如果你希望这个通道在所有迭代中都相同,你应该在循环之前保存它:

    timeout := time.After(3 * time.Second)
    for {
        select {
        //...
        case <-timeout:
            fmt.Printf("timeout\n")
            return
        }
    }
    

    游乐场:http://play.golang.org/p/muWLgTxpNf.

    【讨论】:

    • 太棒了!我正在创建多个频道!谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    • 1970-01-01
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 2018-03-10
    • 2015-04-30
    相关资源
    最近更新 更多