Go進(jìn)階之定時(shí)器Ticker的實(shí)現(xiàn)示例
Ticker是周期性定時(shí)器.即周期性的觸發(fā)一個(gè)事件.通過(guò)Ticker本身提供的管道將事件
傳遞出去.
Ticker數(shù)據(jù)結(jié)構(gòu):
源碼位置:src/time/tick.go
type Ticker struct {
C <-chan Time // The channel on which the ticks are delivered.
initTicker bool
}
Ticker對(duì)外僅暴露了一個(gè)channel.當(dāng)指定時(shí)間到來(lái)時(shí)就往該channel中寫入系統(tǒng)時(shí)
間.即一個(gè)事件.
1.簡(jiǎn)單定時(shí)任務(wù):
func main() {
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
for range ticker.C {
log.Println("tick")
}
}
執(zhí)行結(jié)果:

定時(shí)聚合任務(wù):
示例:
func TickerLaunch() {
//5分鐘執(zhí)行一次.
ticker := time.NewTicker(5 * time.Minute)
defer ticker.Stop()
maxPassenger := 30
passengers := make([]string, 0, maxPassenger)
for {
passenger := GetNewPassenger()
if passenger != "" {
passengers = append(passengers, passenger)
} else {
time.Sleep(1 * time.Second)
}
select {
case <-ticker.C:
Launch(passengers)
passengers = []string{}
default:
if len(passengers) >= maxPassenger {
Launch(passengers)
passengers = []string{}
}
}
}
}
func Launch(passengers []string) {
for i := range passengers {
fmt.Println(passengers[i], "發(fā)車了")
}
}
func GetNewPassenger() string {
return "乘客"
}
2.Ticker對(duì)外接口:
1)創(chuàng)建定時(shí)器:
源碼位置:src/time/tick.go
func NewTicker(d Duration) *Ticker {
if d <= 0 {
panic("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)(unsafe.Pointer(newTimer(when(d), int64(d), sendTime, c, syncTimer(c))))
t.C = c
return t
}

2).停止定時(shí)器:
源碼位置:src/time/tick.go
// Stop turns off a ticker. After Stop, no more ticks will be sent.
// Stop does not close the channel, to prevent a concurrent goroutine
// reading from the channel from seeing an erroneous "tick".
func (t *Ticker) Stop() {
if !t.initTicker {
// This is misuse, and the same for time.Timer would panic,
// but this didn't always panic, and we keep it not panicking
// to avoid breaking old programs. See issue 21874.
return
}
stopTimer((*Timer)(unsafe.Pointer(t)))
}

流程圖:

總流程圖:

3.簡(jiǎn)單接口:
在有些場(chǎng)景下.啟動(dòng)一個(gè)定時(shí)器后.該定時(shí)器永遠(yuǎn)不會(huì)停止.比如定時(shí)輪詢?nèi)蝿?wù).此時(shí)可
以使用一個(gè)簡(jiǎn)單的Tick函數(shù)來(lái)獲取定時(shí)器的管道.函數(shù)如下:
源碼位置:src/runtime/tick.go
func Tick(d Duration) <-chan Time {
if d <= 0 {
return nil
}
return NewTicker(d).C
}
從源碼可以看出其實(shí)是創(chuàng)建了一個(gè)Ticker.然后只返回了管道.并沒(méi)有返回ticker.所以
沒(méi)有辦法停止.
4.錯(cuò)誤示例:
當(dāng)Ticker用于for循環(huán)時(shí).很容易出現(xiàn)意想不到的資源泄漏問(wèn)題.
示例:
func WrongTicker() {
for {
select {
case <-time.Tick(time.Second):
log.Printf("resource leak!")
}
}
}
上面的代碼.select每次檢測(cè)case語(yǔ)句都會(huì)創(chuàng)建一個(gè)定時(shí)器.for循環(huán)又會(huì)不斷的執(zhí)行
select語(yǔ)句.系統(tǒng)里會(huì)有越來(lái)越多的定時(shí)器不斷地消耗CPU資源.最終CPU資源被耗
到此這篇關(guān)于Go進(jìn)階之定時(shí)器Ticker的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)Go 定時(shí)器Ticker內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Windows中Golang編譯運(yùn)行緩慢的解決方法
Go語(yǔ)言編譯運(yùn)行緩慢問(wèn)題可能是由于Windows 11更新引入的PCManagerServiceStore進(jìn)程導(dǎo)致的,該進(jìn)程會(huì)強(qiáng)制檢查Go代碼編譯過(guò)程,消耗大量系統(tǒng)資源,下面就來(lái)介紹一下該問(wèn)題的解決2025-08-08
golang 實(shí)現(xiàn)一個(gè)restful微服務(wù)的操作
這篇文章主要介紹了golang 實(shí)現(xiàn)一個(gè)restful微服務(wù)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04
go語(yǔ)言實(shí)現(xiàn)字符串與其它類型轉(zhuǎn)換(strconv包)
strconv包是Go語(yǔ)言標(biāo)準(zhǔn)庫(kù)的一部分,主要提供字符串與基本數(shù)據(jù)類型之間的轉(zhuǎn)換功能,使用strconv包可以方便地在不同類型之間進(jìn)行轉(zhuǎn)換,滿足日常編程中的需求,感興趣的可以了解一下2024-10-10
Golang 基礎(chǔ)之函數(shù)使用(匿名遞歸閉包)實(shí)例詳解
這篇文章主要為大家介紹了Golang 基礎(chǔ)之函數(shù)使用(匿名遞歸閉包)實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-10-10
一文帶你使用Golang實(shí)現(xiàn)SSH客戶端
SSH?全稱為?Secure?Shell,是一種用于安全地遠(yuǎn)程登錄到網(wǎng)絡(luò)上的其他計(jì)算機(jī)的網(wǎng)絡(luò)協(xié)議,本文主要為大家詳細(xì)介紹了如何使用?Golang?實(shí)現(xiàn)?SSH?客戶端,需要的可以參考下2023-11-11
go語(yǔ)言channel實(shí)現(xiàn)多核并行化運(yùn)行的方法
這篇文章主要介紹了go語(yǔ)言channel實(shí)現(xiàn)多核并行化運(yùn)行的方法,實(shí)例分析了channel實(shí)現(xiàn)多核并行化運(yùn)行的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
Go中的fuzz模糊測(cè)試使用實(shí)戰(zhàn)詳解
這篇文章主要為大家介紹了Go中的fuzz模糊測(cè)試使用實(shí)戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12

