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中

img

目前计时器都交由处理器的网络轮询器和调度器触发,这种方式能够充分利用本地性、减少上下文的切换开销,也是目前性能最佳的实现方式

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从系统协程中删除,修改新的时间后重新添加到系统协程中

posted @   每天提醒自己要学习  阅读(108)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示