为了账号安全,请及时绑定邮箱和手机立即绑定

Ticker 在 time.sleep() 中的行为

Ticker 在 time.sleep() 中的行为

Go
慕容708150 2022-10-17 19:34:44
代码:func main() {    fmt.Println(time.Now())    ticker := time.NewTicker(100 * time.Millisecond)    done := make(chan bool)    go func() {        time.Sleep(900 * time.Millisecond)        for {            select {            case <-done:                return            case t := <-ticker.C:                fmt.Println("Tick at", t)            }        }    }()    time.Sleep(1600 * time.Millisecond)    ticker.Stop()    done <- true    fmt.Println("Ticker stopped")}输出:2021-12-15 17:00:44.2506052 +0800 +08 m=+0.002777301Tick at 2021-12-15 17:00:44.3916764 +0800 +08 m=+0.143848501Tick at 2021-12-15 17:00:45.2913066 +0800 +08 m=+1.043478701Tick at 2021-12-15 17:00:45.4007827 +0800 +08 m=+1.152954801Tick at 2021-12-15 17:00:45.4930864 +0800 +08 m=+1.245258501Tick at 2021-12-15 17:00:45.6021253 +0800 +08 m=+1.354297401Tick at 2021-12-15 17:00:45.6980372 +0800 +08 m=+1.450209301Tick at 2021-12-15 17:00:45.7929148 +0800 +08 m=+1.545086901Tick at 2021-12-15 17:00:45.901921 +0800 +08 m=+1.654093101Ticker stopped问题:我如何解释结果?进一步来说:为什么 goroutine 中的 sleep 会暂停 ticker 而 main 例程中的 sleep 不会?是ticker.C 非缓冲所以没有16 个滴答声?为什么第一个刻度有 m=+0.143848501?
查看完整描述

1 回答

?
守着星空守着你

TA贡献1799条经验 获得超8个赞

  1. goruotine 中的睡眠不会暂停代码,它会延迟第一次打印值的时刻。

  2. ticker.C 的缓冲区为 1。根据代码中的注释:

    // Give the channel a 1-element time buffer.
    // If the client falls behind while reading, we drop ticks
    // on the floor until the client catches up.

所以那里只有一个缓冲值。

  1. 第一个刻度大约在刻度持续时间第一次经过约 100 毫秒的那一刻被写入通道。然后跳过其他滴答声,因为ticker.C 中的缓冲区已满并被丢弃,直到通道在 time.Sleep 之后被解除阻塞,所以我们有大约 900 毫秒的跳跃。


查看完整回答
反对 回复 2022-10-17
  • 1 回答
  • 0 关注
  • 121 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号