Go专家编程-定时器

本文介绍了Go语言中的定时器,包括一次性定时器Timer和周期性定时器Ticker的使用场景、接口、实现原理。Timer适用于设定超时时间或延迟执行,而Ticker则用于周期性任务。内容涵盖如何创建、停止和重置定时器,以及它们的内部数据结构和管理机制。
摘要由CSDN通过智能技术生成

本文为《Go专家编程》读书笔记~



定时器

Go提供了两种定时器,此处分为一次性定时器、周期性定时器。
一次性定时器:定时器只计时一次,结束便停止;
周期性定时器:定时器周期性进行计时,除非主动停止,否则将永久运行;

Timer

Timer实际上是一种单一事件的定时器,即经过指定的时间后触发一个事件,这个事件通过其本身提供的channel进 行通知。之所以叫单一事件,是因为Timer只执行一次就结束,这也是Timer与Ticker的最重要的区别之一。
通过timer.NewTimer(d Duration)可以创建一个timer,参数即等待的时间,时间到来后立即触发一个事件。

type Timer struct {
    // Timer代表一次定时,时间到来后仅发生一个事件。 
	// Timer对外仅暴露一个channel,指定的时间到来时就往该channel中写入系统时间,也即一个事件。
	C <-chan Time 
	r runtimeTimer
}

使用场景

设定超时时间 / 延迟执行某个方法
func WaitChannel(conn <-chan string) bool {
    
	timer := time.NewTimer(1 * time.Second) 
	select {
    
		case <- conn: 
		timer.Stop() 
		return true 
		case <- timer.C: // 超时 
		println("WaitChannel timeout!") 
		return false 
	}
}

WaitChannel作用就是检测指定的管道中是否有数据到来,通过select语句轮询conn和timer.C两个管道,timer 会在1s后向timer.C写入数据,如果1s内conn还没有数据,则会判断为超时

time.AfterFunc()异步

time.AfterFunc()是异步执行的,所以需要在函数最后sleep等待指定的协程退出,否则可能函数结束时协程还未执行。

func main() {
   
	fmt.Println(time.Now())
	<-time.After(time.Second*1)
	fmt.Println(time.Now())
	
	log.Println("AfterFuncDemo start: ", time.Now())
	// time.AfterFunc()是异步执行的,所以需要在函数最后sleep等待指定的协程退出,否 则可能函数结束时协程还未执行。
	time.AfterFunc(time.Second*2, func() {
   
		log.Println("AfterFuncDemo end: ", time.Now())
	})
	time.Sleep(3 * time.Second) // 等待协程退出
}

Timer对外接口

创建定时器

使用方法 func NewTimer(d Duration) *Timer 指定一个时间即可创建一个Timer,Timer一经创建便开始计时,不需要 额外的启动命令。
实际上,创建Timer意味着把一个计时任务交给系统守护协程,该协程管理着所有的Timer,当Timer的时间到达后 向Timer的管道中发送当前的时间作为事件。

停止定时器

Timer创建后可以随时停止,停止计时器的方法是:

1. func (t *Timer) Stop() bool

其返回值代表定时器有没有超时:

  • true: 定时器超时前停止,后续不会再有事件发送;
  • false: 定时器超时后停止;
重置定时器

已过期的定时器或者已停止的定时器,可以通

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值