go語言設定計時器的方法:1、透過「time.NewTicker()」方法創建,其中ticker會依照設定的間隔時間觸發;2、透過「time.NewTimer()」方法創建,其中timer只會執行一詞;3、使用「After()」來創建。
本文環境:Windows7系統、Go1.11.2版,本文適用於所有品牌的電腦。
推薦:《golang教學#》
#Go語言中定時器的使用
GO語言在time套件中提供了三種計時器的使用方式:
1.第一種:ticker
// A Ticker holds a channel that delivers `ticks' of a clock // at intervals. type Ticker struct { C <-chan Time // The channel on which the ticks are delivered. r runtimeTimer }
透過time.NewTicker() 創建,這種類型,ticker會不斷的按照設定的間隔時間觸發,除非主動終止運行。
2.第二種:timer
// The Timer type represents a single event. // When the Timer expires, the current time will be sent on C, // unless the Timer was created by AfterFunc. // A Timer must be created with NewTimer or AfterFunc. type Timer struct { C <-chan Time r runtimeTimer }
#透過 time.NewTimer() 創建,這種類型,timer只會執行一次,當然,可以在執行完以後通過調用timer.Reset() 讓定時器再次運作,並且可以更改時間間隔。
3.第三種:After()
#// After waits for the duration to elapse and then sends the current time // on the returned channel. // It is equivalent to NewTimer(d).C. // The underlying Timer is not recovered by the garbage collector // until the timer fires. If efficiency is a concern, use NewTimer // instead and call Timer.Stop if the timer is no longer needed. func After(d Duration) <-chan Time { return NewTimer(d).C }
從程式碼可以看到,After()其實是Timer的一個語法糖。
下面透過程式碼示範三種方式的使用:
#1.Ticker
ticker := time.NewTicker(time.Second * 1) // 运行时长 ch := make(chan int) go func() { var x int for x < 10 { select { case <-ticker.C: x++ fmt.Printf("%d\n", x) } } ticker.Stop() ch <- 0 }() <-ch // 通过通道阻塞,让任务可以执行完指定的次数。
該ticker每1秒觸發一次,即ticker.C中每一秒會有一個內容加入,最後透過向ch中寫入數字,讓程式解除阻塞,繼續執行。
2.Timer
timer := time.NewTimer(time.Second * 1) // timer 只能按时触发一次,可通过Reset()重置后继续触发。 go func() { var x int for { select { case <-timer.C: x++ fmt.Printf("%d,%s\n", x, time.Now().Format("2006-01-02 15:04:05")) if x < 10 { timer.Reset(time.Second * 2) } else { ch <- x } } } }() <-ch
3.After()
// 阻塞一下,等待主进程结束 tt := time.NewTimer(time.Second * 10) <-tt.C fmt.Println("over.") <-time.After(time.Second * 4) fmt.Println("再等待4秒退出。tt 没有终止,打印出 over 后会看见在继续执行...") tt.Stop() <-time.After(time.Second * 2) fmt.Println("tt.Stop()后, tt 仍继续执行,只是关闭了 tt.C 通道。")
4.我們可以利用這些基本的方法,設計自己的定時任務管理。
type jobFunc2 func(j *job) type job struct { jf jobFunc2 params map[string]interface{} ch chan int } func NewJob() *job { return &job{ params: make(map[string]interface{}), ch: make(chan int), } } func (j *job) Run(t time.Duration) { ticker := time.NewTicker(time.Second * t) go func() { for { select { case <-ticker.C: j.jf(j) case <-j.ch: fmt.Println("收到结束指令") ticker.Stop() break } } }() } func main() { j := NewJob() j.jf = func(jj *job) { fmt.Println("定时任务执行...", time.Now().Format("15:04:05 2006-02-01"), jj.params) } j.params["p1"] = "第一个参数" j.params["p2"] = 100 j.Run(1) // 阻塞一下,等待主进程结束 tt := time.NewTimer(time.Second * 10) <-tt.C fmt.Println("over.") <-time.After(time.Second * 4) fmt.Println("再等待4秒退出。tt 没有终止,打印出 over 后会看见在继续执行...") tt.Stop() <-time.After(time.Second * 2) fmt.Println("tt.Stop()后, tt 仍继续执行,只是关闭了 tt.C 通道。") }
部分執行結果截圖:
# 最後補充一下,透過channel去終止任務的執行。
// 阻塞一下,等待主进程结束 tt := time.NewTimer(time.Second * 10) <-tt.C fmt.Println("over.") <-time.After(time.Second * 4) fmt.Println("再等待4秒退出。tt 没有终止,打印出 over 后会看见在继续执行...") tt.Stop() <-time.After(time.Second * 2) fmt.Println("tt.Stop()后, tt 仍继续执行,只是关闭了 tt.C 通道。") j.ch <- 0 <-time.After(time.Second * 2) fmt.Println("又等了2秒钟...这两秒钟可以看到 tt 没干活了...")
在GO語言編寫中,要熟練使用 channel。
以上是go語言如何設定定時器的詳細內容。更多資訊請關注PHP中文網其他相關文章!