golang中使用timer和ticker
背景
最近开发项目中,需要写全局的定时器,实现定期检查或者更新部分数据结构。
方案
golang中常用timer或者ticker实现定时功能,下面简单介绍下两种的用法和区别
timer
Timer的用法如下,到期被触发后需要reset,才能继续下一次的触发
如下所示,每隔2s,t.C信道会受到一个信号, 初始化timer之后,sleep5s, 然后再过1s就可以受到信号(因为是2s的倍数)
func timerTest() { //d := time.Duration(time.Second*2)
t := time.NewTimer(time.Second * 2)
defer t.Stop()
fmt.Println("timeout...now=", time.Now())
time.Sleep(5 * time.Second) // do something
for {
<-t.C
fmt.Println("timeout...now=", time.Now())
// need reset
t.Reset(time.Second * 2)
}
}
ticker
func tikerTest() { t := time.NewTicker(3 * time.Second)
defer t.Stop()
fmt.Println("main = ", time.Now())
time.Sleep(7 * time.Second) // do something
for {
select {
case <-t.C:
fmt.Println("for", time.Now())
}
}
time.Afterfunc函数
func AfterFuncTest(){ var t *time.Timer
f := func(){
fmt.Printf("Expiration time : %v.
", time.Now())
fmt.Printf("C`s len: %d
", len(t.C))
}
t = time.AfterFunc(1*time.Second, f)
//让当前Goroutine 睡眠2s,确保大于内容的完整
//这样做原因是,time.AfterFunc的调用不会被阻塞。它会以一部的方式在到期事件来临执行我们自定义函数f。
time.Sleep(4 * time.Second)
}
time.After
func AfterTest(){ ch1 := make(chan int, 1)
ch2 := make(chan int, 1)
go func() {
ch1 <- 1
}()
select {
case e1 := <-ch1:
//如果ch1通道成功读取数据,则执行该case处理语句
fmt.Printf("1th case is selected. e1=%v",e1)
case e2 := <-ch2:
//如果ch2通道成功读取数据,则执行该case处理语句
fmt.Printf("2th case is selected. e2=%v",e2)
case <- time.After(2 * time.Second):
fmt.Println("Timed out")
}
}
总结
都可以用来做定时器,设定好时间和事件, 到期会往time.C的信道里发送消息
ticker 不需要重置, timer需要重置才能继续
After 与AfterFunc的区别:
After接口返回一个chan Time, 当时间到时可以读出Timer,
AfterFunc接受一个方法,当时间到时执行这个方法。
参考
https://www.kancloud.cn/digest/batu-go/153534
https://guidao.github.io/go_timer.html
https://blog.csdn.net/lanyang123456/article/details/79794183
以上是 golang中使用timer和ticker 的全部内容, 来源链接: utcz.com/z/517511.html