谷歌 goroutine 的中断模式(速度问题)

我运行一个 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"

        }

    }

}


侃侃无极
浏览 221回答 1
1回答

撒科打诨

它与 的精度有关time.Timer。查看文档time.After:[...] 它相当于 NewTimer(d).C。和文档time.NewTimer:NewTimer 创建一个新的 Timer,它将在至少持续时间 d后在其频道上发送当前时间。(强调我的)这样做的原因是NewTimer委托给运行时(依赖于操作系统的)计时器,使该计时器的行为依赖于底层操作系统(以及 Go 集成的实现)。一般来说,根据我的经验,亚毫秒级粒度在任何语言中都没有很好的跨平台支持,尤其是在 Windows XP 上。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go