go语言time.Timer
go语言time.Timer
Timer是一个一次性的定时器,经过指定的时间后将会触发一个时间,通知调用的goroutine
使用方法
func main() {
timer := time.NewTimer(3 * time.Second)
for {
select {
case t := <-timer.C:
fmt.Println(t)
return
}
}
}
数据结构
Timer
// The Timer type represents a single event.
// When the Timer expires, the current time will be sent on C,
// unless the Timer was created by AfterFunc.
// A Timer must be created with NewTimer or AfterFunc.
type Timer struct {
C <-chan Time
r runtimeTimer
}
Timer代表一次事件,当Timer过期了,当前时间会被发送到channel C中,当Timer是AfterFunc方法创建时除外
- C : 调用者可以通过此channel来接受时间
- r : 系统管理的定时器
runtimeTimer
type runtimeTimer struct {
pp uintptr
when int64 //当前计时器被唤醒的时间
period int64 //两次被唤醒的间隔
f func(any, uintptr) // 每当计时器被唤醒时都会调用的函数
arg any //计时器被唤醒时调用f传入的参数
seq uintptr //计时器被唤醒时调用f传入的参数,与netpoll相关
nextwhen int64 //计时器处于timerModifiedxx状态时,用于摄者when字段
status uint32 //计时器的状态
}
每创建一个Timer就创建一个runtimeTimer计时器,然后把它交给系统进行监控,我们通过设置runtimeTimer过期后的行为来达到定时的目的。所有的计时器都以最小四叉堆的形式存储在处理器runtime.p中
目前计时器都交由处理器的网络轮询器和调度器触发,这种方式能够充分利用本地性、减少上下文的切换开销,也是目前性能最佳的实现方式
NewTimer
func NewTimer(d Duration) *Timer {
c := make(chan Time, 1)
t := &Timer{
C: c,
r: runtimeTimer{
when: when(d),
f: sendTime,
arg: c,
},
}
startTimer(&t.r)
return t
}
- NewTimer()只是构造了一个Timer,然后把Timer.r通过startTimer()交给系统协程维护。
- C 是一个带1个容量的chan,这样做有什么好处呢,原因是chan 无缓冲发送数据就会阻塞,阻塞系统协程,这显然是不行的。
- 回调函数设置为sendTime,执行参数为channel,sendTime就是到点往C 里面发送当前时间的函数
Stop
func (t *Timer) Stop() bool {
if t.r.f == nil {
panic("time: Stop called on uninitialized Timer")
}
return stopTimer(&t.r)
}
对于使用 AfterFunc(d, f) 创建的计时器,如果 t.Stop 返回 false,则计时器已经过期,函数 f 已在自己的 goroutine中启动;Stop 不会等待 f 完成后再返回。如果调用方需要知道 f 是否已完成,则必须显式与 f 协调。
停止Timer,就是把Timer从系统协程中移除
Reset
func (t *Timer) Reset(d Duration) bool {
if t.r.f == nil {
panic("time: Reset called on uninitialized Timer")
}
w := when(d)
return resetTimer(&t.r, w)
}
重置Timer时会先把timer从系统协程中删除,修改新的时间后重新添加到系统协程中
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具