简介
go语言中有些方便的定时器来对程序进行控制,如周期定时器Ticker单一事件定时器
Tiker和Timer实现方式
Timer
1 数据结构
type Timer struct { // Timer代表一次定时,时间到来后仅发生一个事件。
C <-chan Time
r runtimeTimer
}
是单一的定时器,经过指定时间后会触发一个事件,Timer执行一次就结束
2 代码
timer.NewTimer(d Duration)
Ticker
1 数据结构
type Ticker struct {
C <-chan Time
r runtimeTimer
}
Ticker是一个定时器,英文名称有一种滴答水滴的意思,在创建Ticker时会指定一个时间,作为事件触发的周期就是在对外暴露的channel中放入一个时间间隔,在过这段时间之后,会触发规定事件。
创建方式
ticker := time.NewTicker(1 * time.Second)
Ticker和Timer存储
在每个go程序中都有一个协程来控制Ticker和Timer的实现,我们称之为系统协程。
在我们创建一个定时器时,会首先创建一个timer,这个timer指向timersBucket,timersBucket记录timer的指针。
其中timersBucket便是系统协程存储timer的容器,里面有个切片来存储timer,而i便是timer所在切片的下标。
定时器的创建过程
1 创建一个管道
2 创建一个timer并启动(注意此timer不是Timer,而是系统协程所管理的timer。)
创建管道的部分前面已做过介绍,这里我们重点关注timer的启动部分。
首先,每个timer都必须要归属于某个timersBucket的,所以第一步是先选择一个timersBucket,选择的算法很简单,将当前协程所属的Processor ID 与timersBucket数组长度求模,结果就是timersBucket数组的下标。
timer的存储结构
图中每个圆圈代表一个timer,圆圈中的数字代表距离触发事件的秒数,圆圈外的数字代表其在切片中的下标。其中timer 15是新加入的,加入后它被最终调整到数组的1号下,
即将timer排序,逐步运行已经设定好的定时器