go语言中Timer和Ticker两种计时器的使用
作者:m旧裤子
介绍
go语言中有Timer和Ticker这样的两种计时器,两种计时器分别实现了不同的计时功能。
- Timer是单次时间事件,指在指定的单次时间过后触发,然后向自己channel中发送当时时间,此后Timer不再计时。
- Ticker是多次时间事件,指每隔一段事件都触发一次,并向自己channel发送当前时间。
- 类似于javascript中的setTimeout()和setInterval()两种计时器。
Timer计时及其方法
type Timer struct { C <-chan Time // 内含隐藏或非导出字段 }
Timer类型代表单次时间事件。当Timer到期时,当时的时间会被发送给C。
NewTimer
func NewTimer(d Duration) *Timer
NewTimer创建一个Timer,它会在最少过去时间段d后到期,向其自身的C字段发送当时的时间。
使用:
package main import ( "fmt" "time" ) func main() { timer := time.NewTimer(10 * time.Second) t1 := time.Now() fmt.Printf("t1:%v\n", t1) t2 := <-timer.C fmt.Printf("t2:%v\n", t2) }
输出:
t1:2023-04-29 22:13:20.3142549 +0800 CST m=+0.002562901
t2:2023-04-29 22:13:30.328093 +0800 CST m=+10.016401001
程序输出t1后,又计时了10秒输出了t2
Stop
func (t *Timer) Stop() bool
Stop停止Timer的执行。如果停止了t会返回真;如果t已经被停止或者过期了会返回假。Stop不会关闭通道t.C,以避免从该通道的读取不正确的成功。
使用:
package main import ( "fmt" "time" ) func main() { timer := time.NewTimer(10 * time.Second) t1 := time.Now() fmt.Printf("t1:%v\n", t1) //停止计时器 timer.Stop() t2 := time.Now() fmt.Printf("t2:%v\n", t2) t3 := <-timer.C fmt.Printf("t3:%v\n", t3) }
输出:
t1:2023-04-29 22:25:05.921852 +0800 CST m=+0.002725901
t2:2023-04-29 22:25:05.9372012 +0800 CST m=+0.018075101
fatal error: all goroutines are asleep - deadlock!
可见,程序在timer使用了stop方法以后输出t3就报出了all goroutines are asleep - deadlock! 错误。
Reset
func (t *Timer) Reset(d Duration) bool
Reset使t重新开始计时,(本方法返回后再)等待时间段d过去后到期。如果调用时t还在等待中会返回真;如果t已经到期或者被停止了会返回假。
使用:
package main import ( "fmt" "time" ) func main() { timer := time.NewTimer(10 * time.Second) t1 := time.Now() fmt.Printf("t1:%v\n", t1) //程序休眠2s time.Sleep(2 * time.Second) //重新设置时间间隔 timer.Reset(15 * time.Second) t2 := time.Now() fmt.Printf("t2:%v\n", t2) t3 := <-timer.C fmt.Printf("t3:%v\n", t3) }
输出:
t1:2023-04-29 22:33:53.4179209 +0800 CST m=+0.002563001
t2:2023-04-29 22:33:55.4452012 +0800 CST m=+2.029843301
t3:2023-04-29 22:34:10.4605181 +0800 CST m=+17.045160201
计时器被重新设置后会根据设置的时间段重新计时,到时间后,计时结束,向其自身的C字段发送当时的时间。
Ticker计时及其方法
type Ticker struct { C <-chan Time // 周期性传递时间信息的通道 // 内含隐藏或非导出字段 }
Ticker保管一个通道,并每隔一段时间向其传递"tick"。
NewTicker
func NewTicker(d Duration) *Ticker
NewTicker返回一个新的Ticker,该Ticker包含一个通道字段,并会每隔时间段d就向该通道发送当时的时间。它会调整时间间隔或者丢弃tick信息以适应反应慢的接收者。如果d<=0会panic。关闭该Ticker可以释放相关资源。
func (t *Ticker) Stop()
Stop关闭一个Ticker。在关闭后,将不会发送更多的tick信息。Stop不会关闭通道t.C,以避免从该通道的读取不正确的成功。
使用:
package main import ( "fmt" "time" ) func main() { ticker := time.NewTicker(1 * time.Second) a := 10 for { <-ticker.C fmt.Println("a:", a) a-- if a == 0 { ticker.Stop() break } } }
输出;
i: 10
i: 9
i: 8
i: 7
i: 6
i: 5
i: 4
i: 3
i: 2
i: 1
可见,程序中,每隔设置的1s时间就触发一次定时器,并且向自带的channel C中传递当时时间。
到此这篇关于go语言中Timer和Ticker两种计时器的使用的文章就介绍到这了,更多相关go语言 Timer和Ticker内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!