为什么这个Golang代码不能在多个时间内进行选择。

时间:2016-01-27 11:52:58

标签: time go timeout channel

为什么这个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

2 个答案:

答案 0 :(得分:11)

因为time.After是一个函数,所以每次迭代都返回一个新的通道。如果您希望此通道对于所有迭代都相同,则应将其保存在循环之前:

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

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

答案 1 :(得分:4)

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

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
        }
    }
}
相关问题