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")

}

}

 

总结

  1. 都可以用来做定时器,设定好时间和事件, 到期会往time.C的信道里发送消息

  2. ticker 不需要重置, timer需要重置才能继续

  3. 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

回到顶部