GoLang之并发编程-定时器
目录
1.time包
1.1Timer结构体
Timer结构体
Timer类型代表单次时间事件。当Timer到期时,当时的时间会被发送给C,除非Timer是被AfterFunc函数创建的。
type Timer struct {
C <-chan Time
// 内含隐藏或非导出字段
}
Reset方法
Reset使t重新开始计时,(本方法返回后再)等待时间段d过去后到期。如果调用时t还在等待中会返回真;如果t已经到期或者被停止了会返回假。
func (t *Timer) Reset(d Duration) bool
Stop方法
Stop停止Timer的执行。如果停止了t会返回真;如果t已经被停止或者过期了会返回假。Stop不会关闭通道t.C,以避免从该通道的读取不正确的成功。
func (t *Timer) Stop() bool
1.2NewTimer函数
NewTimer创建一个Timer,它会在最少过去时间段d后到期,向其自身的C字段发送当时的时间。
func NewTimer(d Duration) *Timer
1.3AfterFunc函数
AfterFunc另起一个go程等待时间段d过去,然后调用f。它返回一个Timer,可以通过调用其Stop方法来取消等待和对f的调用。
func AfterFunc(d Duration, f func()) *Timer
1.4Tricker结构体
Tricker结构体
Ticker保管一个通道,并每隔一段时间向其传递"tick"。
type Ticker struct {
C <-chan Time // 周期性传递时间信息的通道
// 内含隐藏或非导出字段
}
Stop方法
Stop关闭一个Ticker。在关闭后,将不会发送更多的tick信息。Stop不会关闭通道t.C,以避免从该通道的读取不正确的成功。
func (t *Ticker) Stop()
1.5NewTicker函数
NewTicker返回一个新的Ticker,该Ticker包含一个通道字段,并会每隔时间段d就向该通道发送当时的时间。它会调整时间间隔或者丢弃tick信息以适应反应慢的接收者。如果d<=0会panic。关闭该Ticker可以释放相关资源。
func NewTicker(d Duration) *Ticker
1.6Sleep函数
Sleep阻塞当前go程至少d代表的时间段。d<=0时,Sleep会立刻返回。
func Sleep(d Duration)
1.7After函数
After会在另一线程经过时间段d后向返回值发送当时的时间。等价于NewTimer(d).C。
func After(d Duration) <-chan Time
1.8Tick函数
Tick是NewTicker的封装,只提供对Ticker的通道的访问。如果不需要关闭Ticker,本函数就很方便。
func Tick(d Duration) <-chan Time
2.timer
2.1timer介绍
Timer:时间到了,执行只执行1次
func main() {
// 1.timer基本使用
timer1 := time.NewTimer(2 * time.Second)
t1 := time.Now()
fmt.Printf("t1:%v\n", t1) //t1:2022-09-26 20:00:31.647493 +0800 CST m=+0.024507301
t2 := <-timer1.C
fmt.Printf("t2:%v\n", t2) //t2:2022-09-26 20:00:33.647838 +0800 CST m=+2.024852301
}
func main() {
// 1.timer基本使用
timer1 := time.NewTimer(2 * time.Second)
t1 := time.Now()
fmt.Printf("t1:%v\n", t1)
t2 := <-timer1.C
fmt.Printf("t2:%v\n", t2)
t3 := <-timer1.C
fmt.Printf("t2:%v\n", t3)
/*报错:
t1:2022-09-26 20:17:43.8529544 +0800 CST m=+0.018502801
t2:2022-09-26 20:17:45.8533066 +0800 CST m=+2.018855001
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
D:/all project/go/try/main.go:15 +0x169
*/
}
2.3验证timer只能响应1次
func main() {
// 2.验证timer只能响应1次
timer2 := time.NewTimer(time.Second)
for {
<-timer2.C
fmt.Println("时间到")
}
/*报错
时间到
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
D:/all project/go/try/main.go:11 +0x30
*/
}
2.4timer实现延时的功能
func main() {
// 3.timer实现延时的功能
//(1)
time.Sleep(time.Second)
//(2)
timer3 := time.NewTimer(2 * time.Second)
<-timer3.C
fmt.Println("2秒到") //停顿3秒后输出
//(3)
<-time.After(2 * time.Second)
fmt.Println("2秒到") //停顿两秒后输出
}
func main() {
fmt.Println(time.Now()) //2022-09-26 20:29:16.1361797 +0800 CST m=+0.020503701
time.Sleep(time.Second)
fmt.Println(time.Now()) //2022-09-26 20:29:17.2873802 +0800 CST m=+1.171704201
timer3 := time.NewTimer(2 * time.Second)
<-timer3.C
fmt.Println("2秒到") //与一开始相差三秒
fmt.Println(time.Now()) //2022-09-26 20:29:19.2877282 +0800 CST m=+3.172052201
<-time.After(2 * time.Second)
fmt.Println("2秒到") //与上次相差两秒
fmt.Println(time.Now()) //2022-09-26 20:29:21.2881651 +0800 CST m=+5.172489101
}
2.5停止定时器
func main() {
// 4.停止定时器
timer4 := time.NewTimer(2 * time.Second)
go func() {
<-timer4.C
fmt.Println("定时器执行了")
}()
b := timer4.Stop()
if b {
fmt.Println("timer4已经关闭")
}
/*无论运行多少次,都输出以下
timer4已经关闭
*/
}
2.6重置定时器
func main() {
// 5.重置定时器
timer5 := time.NewTimer(3 * time.Second)
timer5.Reset(1 * time.Second)
fmt.Println(time.Now()) //2022-09-26 20:35:28.5337057 +0800 CST m=+0.029004901
//以下会停顿会再输出
fmt.Println(<-timer5.C) //2022-09-26 20:35:29.5338784 +0800 CST m=+1.029177601
fmt.Println(time.Now()) //2022-09-26 20:35:29.5339321 +0800 CST m=+1.029231301
}
3.Ticker
3.1Ticker介绍
Ticker:时间到了,多次执行
3.2获取ticker对象
func main() {
// 1.获取ticker对象
ticker := time.NewTicker(1 * time.Second)
i := 0
// 子协程
go func() {
for {
//<-ticker.C
i++
fmt.Println(<-ticker.C)
if i == 5 {
//停止
ticker.Stop()
}
}
}()
for {
}
/*
2022-09-26 20:42:28.3611397 +0800 CST m=+1.026178101
2022-09-26 20:42:29.3613138 +0800 CST m=+2.026352201
2022-09-26 20:42:30.3614882 +0800 CST m=+3.026526601
2022-09-26 20:42:31.3616619 +0800 CST m=+4.026700301
2022-09-26 20:42:32.3618361 +0800 CST m=+5.026874501
然后一直卡在这里
*/
}