Go?語(yǔ)言入門之Go?計(jì)時(shí)器介紹
引言
一般來(lái)說(shuō),很多時(shí)候我們面臨這樣一種情況,即我們需要運(yùn)行時(shí)間記錄器,它不斷向我們顯示當(dāng)前時(shí)間或在給定的時(shí)間間隔內(nèi)保持執(zhí)行一定的代碼和平,在這種情況下,我們應(yīng)該使用 ??Ticker?
??,使用這個(gè)我們需要使用 go 語(yǔ)言的 ??time?
?? 包,我們有一個(gè)名為 ??NewTicker()?
?? 的方法,它允許我們停止和啟動(dòng)時(shí)間代碼,我們需要通過(guò)傳遞 ??chan?
?? 和 ??bool?
? 作為將使用的參數(shù)來(lái)創(chuàng)建一個(gè)代碼通道檢查它是否打開(kāi),如果通道打開(kāi)意味著計(jì)時(shí)器將繼續(xù)。
Go 的計(jì)時(shí)器
Go 提供了非常簡(jiǎn)單的語(yǔ)法來(lái)實(shí)現(xiàn)一個(gè)計(jì)時(shí)器,定時(shí)器的結(jié)構(gòu)體定義:
type Ticker struct { C <-chan Time // 拋出來(lái)的channel,給上層系統(tǒng)使用,實(shí)現(xiàn)計(jì)時(shí) r runtimeTimer // 給系統(tǒng)管理使用的定時(shí)器,系統(tǒng)通過(guò)該字段確定定時(shí)器是否到時(shí),如果到時(shí),調(diào)用對(duì)應(yīng)的函數(shù)向C中推送當(dāng)前時(shí)間。 }
Ticker對(duì)外僅暴露一個(gè) channel,指定的時(shí)間到來(lái)時(shí)就往該 channel 中寫(xiě)入系統(tǒng)時(shí)間,也即一個(gè)事件。
Ticker 的使用方式也很簡(jiǎn)單,代碼如下:
import time TimeTicker := time.NewTicker(1 * time.Second) TimeTicker.Stop()
- ?
?time?
?? : 如果想要使用??time?
? 中的計(jì)時(shí)器,那么需要將其導(dǎo)入代碼中 - ?
?NewTicker()?
?? 函數(shù):這個(gè)很好理解,新建一個(gè)計(jì)時(shí)器,然后該計(jì)時(shí)器以時(shí)間表達(dá)式作為參數(shù),比如一秒??1*time.Second?
?? ,而不是直接傳入??1?
?? ,也可以傳入其他時(shí)間方式,比如??2*time.Millisecond?
? - 最后,我們可以使用時(shí)間表達(dá)式調(diào)用由?
?NewTicker?
?? 函數(shù)創(chuàng)建的變量上的任何活動(dòng)。例如,在上面的語(yǔ)法中,我們使用了??TimeTicker.Stop()?
?? 來(lái)停止時(shí)間計(jì)時(shí)器。我們可以在特定條件下使用它,比如定義倒數(shù) 10 秒的計(jì)時(shí)器,就可以檢查時(shí)間是否滿足 10 秒,一旦 10 秒發(fā)生,我們可以調(diào)用??TimeTicker.stop()?
?。
我們可以每隔一秒輸出一個(gè)結(jié)果,比如實(shí)現(xiàn)一個(gè)倒數(shù) 10 個(gè)數(shù)的功能:
package main import ( "fmt" "time" ) func main() { TimeTicker := time.NewTicker(1 * time.Second) i := 10 for { <-TimeTicker.C fmt.Println("i = ", i) i-- if i == 0 { TimeTicker.Stop() break } } }
然后執(zhí)行該程序:
$ go run main.go
i = 10
i = 9
i = 8
i = 7
i = 6
i = 5
i = 4
i = 3
i = 2
i = 1
Ticker 計(jì)時(shí)器是如何工作的?
??NewTicker?
??創(chuàng)建的計(jì)時(shí)器與??NewTimer?
??創(chuàng)建的計(jì)時(shí)器持有的時(shí)間??channel?
??一樣都是帶一個(gè)緩存的??channel?
??,每次觸發(fā)后執(zhí)行的函數(shù)也是??sendTime?
??,這樣即保證了無(wú)論有誤接收方??Ticker?
?觸發(fā)時(shí)間事件時(shí)都不會(huì)阻塞:
func NewTicker(d Duration) *Ticker { if d <= 0 { panic(errors.New("non-positive interval for NewTicker")) } // Give the channel a 1-element time buffer. // If the client falls behind while reading, we drop ticks // on the floor until the client catches up. c := make(chan Time, 1) t := &Ticker{ C: c, r: runtimeTimer{ when: when(d), period: int64(d), f: sendTime, arg: c, }, } startTimer(&t.r) return t }
NewTicker()只是構(gòu)造了一個(gè)Ticker,然后把Ticker.r通過(guò)startTimer()交給系統(tǒng)協(xié)程維護(hù)。
其中period
為事件觸發(fā)的周期。
其中??sendTime()?
?方法便是定時(shí)器觸發(fā)時(shí)的動(dòng)作:
func sendTime(c interface{}, seq uintptr) { select { case c.(chan Time) <- Now(): default: } }
??sendTime?
? 接收一個(gè)管道作為參數(shù),其主要任務(wù)是向管道中寫(xiě)入當(dāng)前時(shí)間。
停止Ticker:
停止Ticker
,只是簡(jiǎn)單的把Ticker從系統(tǒng)協(xié)程中移除。
函數(shù)主要實(shí)現(xiàn)如下:
func (t *Ticker) Stop() { stopTimer(&t.r) }
??stopTicker()?
? 即通知系統(tǒng)協(xié)程把該 Ticker 移除,即不再監(jiān)控。系統(tǒng)協(xié)程只是移除 Ticker 并不會(huì)關(guān)閉管道,以避免用戶協(xié)程讀取錯(cuò)誤。
Ticker 使用方式
例子一:
package main import ( "fmt" "time" ) func main() { TimeTicker := time.NewTicker(3 * time.Second) tickerChannel := make(chan bool) go func() { for { select { case timeticker := <-TimeTicker.C: fmt.Println("The time for current is : ", timeticker) case <-tickerChannel: return } } }() time.Sleep(6 * time.Second) TimeTicker.Stop() tickerChannel <- true fmt.Println("Time for running ticker is completed") }
運(yùn)行該代碼:
$ go run main.go
The time for current is : 2022-04-29 22:37:13.93862 +0800 CST m=+3.000267823
The time for current is : 2022-04-29 22:37:16.939081 +0800 CST m=+6.000707515
Time for running ticker is completed
例子二:
package main import ( "fmt" "time" ) func main() { tm := time.Millisecond tickerTicker := time.NewTicker(400 * tm) tickerChaneel := make(chan bool) go func() { for { select { case <-tickerChaneel: return case tmtr := <-tickerTicker.C: fmt.Println("Ticker time at current is", tmtr) } } }() time.Sleep(1400 * time.Millisecond) tickerTicker.Stop() tickerChaneel <- true fmt.Println("Ticker has stopped now") }
運(yùn)行該代碼:
$ go run main.go
Ticker time at current is 2022-04-29 22:39:51.13057 +0800 CST m=+0.400159916
Ticker time at current is 2022-04-29 22:39:51.531516 +0800 CST m=+0.801102997
Ticker time at current is 2022-04-29 22:39:51.931238 +0800 CST m=+1.200822301
Ticker has stopped now
總結(jié)
本文簡(jiǎn)單了解了 go 計(jì)時(shí)器 ??Ticker?
?? 的基本概念,介紹了它的工作原理,并且我們專注于 go 語(yǔ)言中 ??ticker?
? 的語(yǔ)法和使用。最后展現(xiàn)了 go 語(yǔ)言中的一些重要示例。
到此這篇關(guān)于Go 語(yǔ)言入門之Go 計(jì)時(shí)器介紹的文章就介紹到這了,更多相關(guān)Go計(jì)時(shí)器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Go1.18新特性使用Generics泛型進(jìn)行流式處理
這篇文章主要為大家介紹了Go1.18新特性使用Generics泛型進(jìn)行流式處理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06go判斷文件夾是否存在并創(chuàng)建的實(shí)例
這篇文章主要介紹了go判斷文件夾是否存在,并創(chuàng)建的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12解決go mod私有倉(cāng)庫(kù)拉取的問(wèn)題
這篇文章主要介紹了解決go mod私有倉(cāng)庫(kù)拉取的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-05-05Go?數(shù)據(jù)結(jié)構(gòu)之二叉樹(shù)詳情
這篇文章主要介紹了?Go?數(shù)據(jù)結(jié)構(gòu)之二叉樹(shù)詳情,二叉樹(shù)是一種數(shù)據(jù)結(jié)構(gòu),在每個(gè)節(jié)點(diǎn)下面最多存在兩個(gè)其他節(jié)點(diǎn)。即一個(gè)節(jié)點(diǎn)要么連接至一個(gè)、兩個(gè)節(jié)點(diǎn)或不連接其他節(jié)點(diǎn),下文基于GO語(yǔ)言展開(kāi)二叉樹(shù)結(jié)構(gòu)詳情,需要的朋友可以參考一下2022-05-05Windows下Goland的環(huán)境搭建過(guò)程詳解
這篇文章主要介紹了Windows下Goland的環(huán)境搭建過(guò)程,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10GO語(yǔ)言利用K近鄰算法實(shí)現(xiàn)小說(shuō)鑒黃
本文給大家分享的是一段GO語(yǔ)言利用K近鄰算法實(shí)現(xiàn)小說(shuō)鑒黃的方法,本方法的鑒別的關(guān)鍵是關(guān)鍵是向量點(diǎn)的選擇和閾值的判定,推薦給大家,有需要的小伙伴可以參考下。2015-03-03go語(yǔ)言實(shí)現(xiàn)順序存儲(chǔ)的棧
這篇文章主要介紹了go語(yǔ)言實(shí)現(xiàn)順序存儲(chǔ)的棧,實(shí)例分析了Go語(yǔ)言實(shí)現(xiàn)順序存儲(chǔ)的棧的原理與各種常見(jiàn)的操作技巧,需要的朋友可以參考下2015-03-03