定时器
go中time包中定时器主要有三种,Sleep、Timer、Ticker。下面逐一来进行说明。
1: Sleep
可以通过Sleep进行指定时间的睡眠。
func Sleep(d Duration)
例如延迟三秒中后输出hello,world。
time.Sleep(time.Second * 3)
fmt.Println("hello,world")
2:Timer
Timer是一个定时器,代表未来的一个单一事件,你可以告诉timer你要等待多长时间。
type Timer struct {
C <-chan Time
r runtimeTimer
}
它提供一个channel,在定时时间到达之前,没有数据写入timer.C会一直阻塞。直到定时时间到,向channel写入值,阻塞解除,可以从中读取数据。
package main
import (
"fmt"
"time"
)
func main() {
// 创建一个定时器
timer1 := time.NewTimer(time.Second * 3) // 当三秒后定时器会向自己的c字节发送一个time.Time类型的元素值
fmt.Println("现在的时间:",time.Now())
t := <- timer1.C
fmt.Println("接收到的时间:",t)
}
输出的结果:
现在的时间: 2020-03-21 10:30:22.064938 +0800 CST m=+0.000127008
接收到的时间: 2020-03-21 10:30:25.069487 +0800 CST m=+3.004669121
Process finished with exit code 0
如果只是单纯的想要睡眠延迟,建议使用time.Sleep()。
在其中,还有一个time.After()函数,作用是指定时间之后向返回的chan中写入时间。
func After(d Duration) <-chan Time {
return NewTimer(d).C
}
从上面的源码中可以看出,time.After()是通过NewTimer实现。如果想要让效率更高一点,可以使用NewTimer。
示例:
t := time.After(time.Second*2)
fmt.Println(<-t) // 会在2秒钟之后得到结果
通常来说,可以通过select 和 time.Affer的结合,实现超时控制。
package main
import (
"time"
"fmt"
)
func main() {
ch := make(chan string)
go func() {
time.Sleep(time.Second * 2)
ch <- "result"
}()
select {
case res := <-ch:
fmt.Println(res)
case <-time.After(time.Second * 1):
fmt.Println("timeout")
}
}
定时器整理:
-
实现延迟功能。
-
<-time.After(2 * time.Second) // 定时2s,阻塞2s,2s后产生一个事件,往channel写内容
-
time.Sleep(2 * time.Second) // 睡眠延迟2秒
-
timer := time.NewTimer(2 * time.Second) // 延迟两秒 写入时间 <- timer.C
-
-
停止定时器
-
timer := time.NewTimer(3 * time.Second) go func() { <-timer.C fmt.Println("子协程可以打印了,因为定时器的时间到") }() timer.Stop() //停止定时器 for { ; }
-
-
定时器重置
-
timer := time.NewTimer(3 * time.Second) ok := timer.Reset(1 * time.Second) //重新设置为1s fmt.Println("ok = ", ok) <-timer.C fmt.Println("时间到")
-
3: Ticker
Ticker是一个周期触发定时的计时器,它会按照一个时间间隔往channel发送系统当前时间,而channel的接收者可以以固定的时间间隔从channel中读取事件。
type Ticker struct {
C <-chan Time // The channel on which the ticks are delivered.
r runtimeTimer
}
例如:
package main
import (
"fmt"
"time"
)
func main() {
// 创建一个周期定时ticker
ticker := time.NewTicker(time.Second * 3)
for {
t := <-ticker.C
fmt.Println(t)
}
}
上面的代码中,每隔三秒就能获取一个时间。