定时器
定时器
time.Timer
Timer是一个定时器。代表未来的一个单一事件,你可以告诉timer你要等待多长时间。
type Timer struct {
C <-chan Time
r runtimeTimer
}
它提供一个channel,在定时时间到达之前,没有数据写入timer.C会一直阻塞。直到定时时间到,系统会自动向timer.C 这个channel中写入当前时间,阻塞即被解除。
示例代码:
package main
import (
"fmt"
"time"
)
func main() {
//创建定时器,2秒后,定时器就会向自己的C字节发送一个time.Time类型的元素值
timer1 := time.NewTimer(time.Second * 2)
t1 := time.Now() //当前时间
fmt.Printf("t1: %v\n", t1)
t2 := <-timer1.C
fmt.Printf("t2: %v\n", t2)
//如果只是想单纯的等待的话,可以使用 time.Sleep 来实现
timer2 := time.NewTimer(time.Second * 2)
<-timer2.C
fmt.Println("2s后")
time.Sleep(time.Second * 2)
fmt.Println("再一次2s后")
<-time.After(time.Second * 2)
fmt.Println("再再一次2s后")
timer3 := time.NewTimer(time.Second)
go func() {
<-timer3.C
fmt.Println("Timer 3 expired")
}()
stop := timer3.Stop() //停止定时器
if stop {
fmt.Println("Timer 3 stopped")
}
fmt.Println("before")
timer4 := time.NewTimer(time.Second * 5) //原来设置3s
timer4.Reset(time.Second * 1) //重新设置时间
<-timer4.C
fmt.Println("after")
}
定时器的常用操作:
- 实现延迟功能
1) <-time.After(2 * time.Second) //定时2s,阻塞2s,2s后产生一个事件,往channel写内容
fmt.Println(“时间到”)2) time.Sleep(2 * time.Second)
fmt.Println(“时间到”)3) 延时2s后打印一句话
timer := time.NewTimer(2 * time.Second)
<- timer.C
fmt.Println(“时间到”)
- 定时器停止
timer := time.NewTimer(3 * time.Second)
go func() {
<-timer.C
fmt.Println("子go程可以打印了,因为定时器的时间到")
}()
timer.Stop() //停止定时器
for {
}
- 定时器重置
timer := time.NewTimer(3 * time.Second)
ok := timer.Reset(1 * time.Second) //重新设置为1s
fmt.Println("ok = ", ok)
<-timer.C
fmt.Println("时间到")
time.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() {
//创建定时器,每隔1秒后,定时器就会给channel发送一个事件(当前时间)
ticker := time.NewTicker(time.Second * 1)
i := 0
go func() {
for { //循环
<-ticker.C
i++
fmt.Println("i = ", i)
if i == 5 {
ticker.Stop() //停止定时器
break //return/Goexit()
}
}
}() //别忘了()
//死循环,特地不让main goroutine结束
for {
}
}
练习题
编程实现,主、子go程交替数数。
假设有全局变量 glb = 1 初值为1。
子go程打印1,主go程打印 2,子go程打印3, 主go程打印 4, 子go程打印 5, 主go程 打印 6 ……
以此类推。要求不使用 sleep函数,完成正常打印。