Go语言的标准库里提供两种类型的计时器Timer和Ticker。
Timer
经过指定的duration时间后被触发,往自己的时间channel发送当前时间,此后Timer不再计时。
Ticker
每隔duration时间都会把当前时间点发送给自己的时间channel,利用计时器的时间channel可以实现很多与计时相关的功能。
time.Timer
和
time.Ticker
的结构体
// Timer.C和Ticker.C就是计时器中的时间channel
type Timer struct {
C <-chan Time
r runtimeTimer
}
type Ticker struct {
C <-chan Time
r runtimeTimer
}
Timer计时器
Timer 对象 以及 time.After 方法,都有一次使用的特性
myTimer := time.NewTimer(time.Second * 5)
for {
select {
case <-myTimer.C:
...
myTimer.Reset(time.Second * 5) // 重置
// 此处注意:程序已经从t.C接收到值,则计时器是已知的已过期,t.Reset可以直接使用,否则必须先停止计时器(t.Stop)
}
}
// 不使用,结束
myTimer.Stop()
// 本质创建了一个新的Timer结构体,timeChannel是结构体中的channel字段,不可复用
// for循环中不可用time.After,会不断创建Timer
timeChannel := time.After(time.Second * 10)
select {
case <-timeChannel:
...
}
// Timer常见的使用方法如下:
//使用time.After:
select {
case m := <-c:
handle(m)
case <-time.After(5 * time.Minute):
fmt.Println("timed out")
}
// 使用time.NewTimer:
t := time.NewTimer(5 * time.Minute)
select {
case m := <-c:
handle(m)
case <-t.C:
fmt.Println("timed out")
}
Ticker计时器
Ticker
可以周期性地触发时间事件,按一定时间间隔重复执行任务
ticker := time.NewTicker(3 * time.Second)
for {
<-ticker.C
...
}
ticker.Stop()
// 1秒执行一次,5秒后停止
var ticker *time.Ticker = time.NewTicker(1 * time.Second)
go func() {
for t := range ticker.C {
fmt.Println("Tick at", t)
}
}()
time.Sleep(time.Second * 5)
ticker.Stop()
fmt.Println("Ticker stopped")
Timer
和
Ticker
的时间channel都是带有一个缓冲的通道。
time.After,time.NewTimer,time.NewTicker创建的计时器触发时都会执行
sendTime
sendTime
和计时器带缓冲的时间通道保证了计时器不会阻塞程序。
参考
版权声明:本文为qq_41502108原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。