1

我运行一个 goroutine 来增加一个计数器,它可以被命令行输入“t\n”打断

select语句中,如果我选择使用default:,计数器变量会j向前飞。这对我来说似乎很正常。

但是,如果我选择使用case <-time.After(100*time.Microsecond):,则计数器j在一秒钟内只加到 60 左右,而不是 10,000。

事实上,无论我输入什么值time.After(),我都只能得到大约 60Hz 的运行频率select

为什么?

package main
import (
    "bufio"
    "fmt"
    "os"
    "strings"
    "time"
)

func main() {
    message := make(chan string)
    go check_input(message)
    work_loop(message)
}

func work_loop(message chan string) {
    //var j [][]int
    var j int
    t0:=time.Now()
Loop:
    for {
        select {
        case msg := <-message:
            if msg == "terminate" {
                //fmt.Println("end task")
                t1:=time.Now()
                fmt.Println(j)
                fmt.Println("total duration:", t1.Sub(t0))
                break Loop
            }
        case <-time.After(100 * time.Microsecond):
        //default:
            //do work here          
            j += 1
            fmt.Println(j)
            break

        }
    }
    //fmt.Println("exit work loop")
}

func check_input(msg chan string) {
    reader := bufio.NewReader(os.Stdin)
    for {
        line, err := reader.ReadString('\n')

        if err != nil {
            // You may check here if err == io.EOF
            break
        }

        if strings.TrimSpace(line) == "t" {
            msg <- "terminate"
        }
    }
}
4

1 回答 1

1

它与 的精度有关time.Timer。查看以下文档time.After

[...] 它相当于 NewTimer(d).C。

和以下文件time.NewTimer

NewTimer 创建一个新的 Timer,它将在至少持续时间 d之后在其通道上发送当前时间。

(强调我的)

这样做的原因是NewTimer委托给一个运行时(依赖于操作系统的)定时器,使这个定时器的行为依赖于底层操作系统(以及 Go 集成的实现)。

一般来说,根据我的经验,亚毫秒粒度在任何语言中都没有很好的跨平台支持,尤其是在 Windows XP 上。

于 2014-02-09T10:19:23.883 回答