c++ 定时器_Go之定时器的使用

一、背景介绍

笔者最近在使用Go的定时器,发现Go提供的time包里面,按照下面几种场景做了区分,并分别提供一些API支持。主要场景如下所示:

1.超时一次之后,就不再使用的定时器,time.After()。2.每隔一段时间,就需要使用一次的定时器,time.Tick()。3.阻塞住goroutinue的定时器,time.Sleep(),准确来说这个不算一个定时器4.可以自由控制定时器启动和关闭的定时器,time.Ticker()。

二、实例演练

1. time.After()

调用time.After(duration),此函数马上返回,返回一个time.Time类型的Chan,不阻塞。后面你该做什么做什么,不影响。到了duration时间后,自动塞一个当前时间进去,底层是用NewTimer实现的。

参考:https://golang.org/pkg/time/#After

func After(d Duration) 

After waits for the duration to elapse and then sends the current time on the returned channel. It is equivalent to NewTimer(d).C. The underlying Timer is not recovered by the garbage collector until the timer fires. If efficiency is a concern, use NewTimer instead and call Timer.Stop if the timer is no longer needed.

例子:

代码:package mainimport (  "fmt"  "time")func main() {  tchan := time.After(time.Second * 3)  fmt.Println(time.Now().String(),"tchan type:%T", tchan)  fmt.Println(time.Now().String(),"mark 1")  fmt.Println(time.Now().String(),"tchan=", 

场景讲解:

使用了time.After之后,只有在调用了

2. time.Tick()

Tick函数是使用channel阻塞当前协程,完成定时任务的执行,用来处理间隔一段固定时间来处理一部分事情的。原文如下:https://golang.org/pkg/time/#Tick

func Tick(d Duration) 

Tick is a convenience wrapper for NewTicker providing access to the ticking channel only. While Tick is useful for clients that have no need to shut down the Ticker, be aware that without a way to shut it down the underlying Ticker cannot be recovered by the garbage collector; it "leaks". Unlike NewTicker, Tick will return nil if d <= 0.

例子:

代码:package mainimport (  "fmt"  "time")func main() {  c := time.Tick(2 * time.Second)   for next := range c {        fmt.Printf("%v ", next)    }}结果输出:timeout running program2009-11-10 23:00:02 +0000 UTC m=+2.000000001 2009-11-10 23:00:04 +0000 UTC m=+4.000000001 2009-11-10 23:00:06 +0000 UTC m=+6.000000001 2009-11-10 23:00:08 +0000 UTC m=+8.000000001

场景讲解:

这段代码是希望每次间隔2秒钟执行一次打印操作,备注:对于Tick来说,返回的是一个只读channel,这里的channel不要使用者做额外的操作,只需要使用就可以,因为这个Tick针对的场景就是那种不需要关闭时间的场景。

3. time.Sleep()

Sleep是使用睡眠完成定时,结束后继续往下执行循环来实现定时任务,Sleep的过程中是会阻塞当前goroutinue的。原文参考:https://golang.org/pkg/time/#Sleep

func Sleep(d Duration)

Sleep pauses the current goroutine for at least the duration d. A negative or zero duration causes Sleep to return immediately.

例子:

代码:package mainimport (  "fmt"  "time")func main() {  for {        fmt.Printf("start %v ", time.Now())        time.Sleep(2 * time.Second)     // time.Sleep的过程中,下面的打印不会执行       fmt.Printf("end %v ", time.Now())    }}结果输出:timeout running programstart 2009-11-10 23:00:00 +0000 UTC m=+0.000000001 end 2009-11-10 23:00:02 +0000 UTC m=+2.000000001 start 2009-11-10 23:00:02 +0000 UTC m=+2.000000001 end 2009-11-10 23:00:04 +0000 UTC m=+4.000000001 start 2009-11-10 23:00:04 +0000 UTC m=+4.000000001 end 2009-11-10 23:00:06 +0000 UTC m=+6.000000001 start 2009-11-10 23:00:06 +0000 UTC m=+6.000000001 end 2009-11-10 23:00:08 +0000 UTC m=+8.000000001 .......

场景讲解:

从执行的打印来看,Sleep被调用之后,当前的goroutine是被阻塞住的,只有Sleep的时间到了之后,才会继续执行后续的操作。

4.time.Ticker

Ticker 和 Timer 类似,区别是:Ticker 中的 runtimeTimer 字段的 period 字段会赋值为 NewTicker(d Duration) 中的 d,表示每间隔 d 纳秒,定时器就会触发一次。

除非程序终止前定时器一直需要触发,否则,不需要时应该调用 Ticker.Stop 来释放相关资源。

原文参考如下:https://golang.org/pkg/time/#Ticker

76c67a8cf1653b4bac12a3f00979ab8b.png

例子:

代码:package mainimport (  "fmt"  "time")func main() {  ticker := time.NewTicker(time.Second)    defer ticker.Stop()    done := make(chan bool)    go func() {        time.Sleep(5 * time.Second) // 5s后触发time.Stop,关闭ticker        done 

场景讲解:希望每隔1s执行一次打印操作,等待5s之后,终止这个操作。通过上面的输出我们能够看出来,time.Stop在调用了之后,timer便不再继续执行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值