Go总结(二三)| 定时器Timer
很多时候我们需要用到定时器,比如定期执行一段逻辑。Go语言中用到最多无外乎几种:
- time.Sleep()
- time.NewTimer()
- time.After()
- time.NewTicker()
这三种底层逻辑都是相通的。具体看网上的介绍。
Sleep和NewTimer
这两个方法类似,你可能会发现NewTimer的实现是放在sleep.go文件当中的。这两种方法都是等待指定的时间长度,只不过sleep直接阻塞执行流,NewTimer是通过发送通道信号的方式,一般用在不同协程间。他们都是一次性的,不会像NewTicker一样定时循环。
NewTimer可以通过Reset()方法再次指定时间激活。
time.After是基于NewTimer实现的,这里不介绍。
NewTicker重点分析
先看一下最常见的用法
|
|
运行结果如下,注意看日志的时间:
2023/02/16 16:26:15 Ticker counter: 1
2023/02/16 16:26:17 Ticker counter: 2
2023/02/16 16:26:19 Ticker counter: 3
2023/02/16 16:26:21 Ticker counter: 4
2023/02/16 16:26:23 Ticker counter: 5
2023/02/16 16:26:25 Ticker counter: 6
2023/02/16 16:26:27 Ticker counter: 7
2023/02/16 16:26:29 Ticker counter: 8
2023/02/16 16:26:31 Ticker counter: 9
2023/02/16 16:26:33 Ticker counter: 10
2023/02/16 16:26:35 Ticker counter: 11
2023/02/16 16:26:37 Ticker counter: 12
2023/02/16 16:26:38 Ticker ready to exit.
2023/02/16 16:26:39 Ticker counter: 13
2023/02/16 16:26:41 Ticker counter: 14
2023/02/16 16:26:43 Ticker counter: 15
2023/02/16 16:26:43 Ticker demo exit.
2023/02/16 16:26:48 Bye.
修改一下,加上一行time.Sleep(10 * time.Second)
,就是把上面Demo中的注释去掉,结果如下:
2023/02/16 16:02:51 Ticker counter: 1
2023/02/16 16:03:01 Ticker counter: 2
2023/02/16 16:03:11 Ticker counter: 3
2023/02/16 16:03:14 Ticker ready to exit.
2023/02/16 16:03:21 Ticker demo exit.
2023/02/16 16:03:24 Bye.
再改10秒换成9秒time.Sleep(9 * time.Second)
,结果如下:
2023/02/16 16:30:05 Ticker counter: 1
2023/02/16 16:30:14 Ticker counter: 2
2023/02/16 16:30:23 Ticker counter: 3
2023/02/16 16:30:28 Ticker ready to exit.
2023/02/16 16:30:32 Ticker counter: 4
2023/02/16 16:30:38 Bye.
各种修改参数测试之后,这里得出几个结论:
- NewTicker第一次触发是在经过第一个时间间隔之后,而不是创建时。
- 如果ticker.C没被接收,下次时间间隔到了产生的新信号直接丢弃,而不会累计。
- 通道select语法其中一个case阻塞的话,其它case即使有通道数据到达也无法运行。
标准库源码分析
参考阅读:
https://www.jianshu.com/p/85205e236418
https://draveness.me/golang/docs/part3-runtime/ch06-concurrency/golang-timer/
标准库的定时器精度能做到MS级别,但是大量的定时任务对运行时性能影响会比较大,因为精度太高。
时间轮定时器
参考阅读:
https://xiaorui.cc/archives/6160
https://segmentfault.com/a/1190000041429846
https://zhuanlan.zhihu.com/p/515198640
时间轮方案被设计来处理大量定时任务,该方案能尽量减少循环遍历带来的性能下降。
(完)
- 原文作者: 闪电侠
- 原文链接:https://chende.ren/2023/02/16161845-008-timer.html
- 版权声明:本作品采用 开放的「署名 4.0 国际 (CC BY 4.0)」创作共享协议 进行许可