簡(jiǎn)介
定時(shí)器是任何編程語(yǔ)言的重要工具传睹,它允許開發(fā)人員在特定時(shí)間間隔安排任務(wù)或執(zhí)行代碼。在 Go 中岸晦,定時(shí)器是通過(guò) time
包實(shí)現(xiàn)的欧啤,該包提供了一系列功能來(lái)創(chuàng)建、啟動(dòng)启上、停止和有效處理定時(shí)器邢隧。我們將探索 Go 中定時(shí)器的強(qiáng)大功能,并通過(guò)代碼示例演示如何在應(yīng)用程序中使用定時(shí)器冈在。
創(chuàng)建計(jì)時(shí)器
要在 Go 中創(chuàng)建一個(gè)定時(shí)器倒慧,我們可以使用 time.NewTimer()
函數(shù),該函數(shù)將持續(xù)時(shí)間作為參數(shù)。下面是一個(gè)示例:
func CreateTimer() {
timer := time.NewTimer(2 * time.Second)
fmt.Println("Timer created.")
<-timer.C // 阻塞
fmt.Println("Timer expired.")
}
在上述代碼片段中纫谅,我們使用 time.NewTimer()
創(chuàng)建了一個(gè)持續(xù)時(shí)間為 2 秒的新定時(shí)器炫贤。<-timer.C
語(yǔ)句會(huì)阻塞執(zhí)行,直到定時(shí)器過(guò)期付秕。定時(shí)器到期后兰珍,"Timer expired."(定時(shí)器已過(guò)期)信息將打印到控制臺(tái)。
停止計(jì)時(shí)器
在某些情況下询吴,您可能想在定時(shí)器到期前停止它掠河。為此,您可以使用定時(shí)器對(duì)象的 Stop()
方法猛计。讓我們修改之前的示例唠摹,加入定時(shí)器停止功能:
func StopTimer() {
timer := time.NewTimer(2 * time.Second)
fmt.Println("Timer created.")
go func() {
<-timer.C
fmt.Println("Timer expired.")
}()
time.Sleep(1 * time.Second)
stopped := timer.Stop()
if stopped {
fmt.Println("Timer stopped.")
} else {
fmt.Println("Timer has already expired.")
}
}
在更新后的代碼中,我們創(chuàng)建了一個(gè) goroutine 來(lái)處理定時(shí)器過(guò)期有滑,這樣就可以在定時(shí)器過(guò)期前停止它跃闹。我們使用 time.Sleep()
函數(shù)來(lái)模擬在嘗試停止計(jì)時(shí)器之前正在進(jìn)行的一些工作。最后毛好,我們調(diào)用 timer.Stop()
停止定時(shí)器望艺。如果定時(shí)器已過(guò)期,timer.Stop()
返回 false肌访,并打印 "定時(shí)器已過(guò)期"找默。否則,我們將打印 "定時(shí)器已停止"吼驶。
重置計(jì)時(shí)器
Go 還提供了重置活動(dòng)定時(shí)器的方法惩激。通過(guò) Reset()
方法,您可以更改活動(dòng)定時(shí)器的持續(xù)時(shí)間蟹演,重新開始倒計(jì)時(shí)风钻。下面是一個(gè)示例:
func ResetTimer() {
timer := time.NewTimer(10 * time.Second)
fmt.Printf("time: %d, Timer created.\n", time.Now().Unix())
time.Sleep(2 * time.Second)
reset := timer.Reset(3 * time.Second)
if reset {
fmt.Printf("time: %d, Timer reset.\n", time.Now().Unix())
} else {
fmt.Printf("time: %d, Timer has already expired.\n", time.Now().Unix())
}
<-timer.C // 阻塞
fmt.Printf("time: %d, Timer expired again.\n", time.Now().Unix())
}
輸出為:
time: 1695183503, Timer created.
time: 1695183505, Timer reset.
time: 1695183508, Timer expired again.
在上述代碼中,我們創(chuàng)建了一個(gè)持續(xù)時(shí)間為 10 秒的計(jì)時(shí)器酒请。使用 time.Sleep()
等待 2 秒后骡技,我們調(diào)用 timer.Reset()
,新的持續(xù)時(shí)間為 3 秒羞反。如果定時(shí)器尚未過(guò)期布朦,則重置操作成功,我們將打印 "定時(shí)器重置"昼窗。否則是趴,進(jìn)入到 <-timer.C
阻塞階段,然后打印 我們將打印 "Timer expired again."澄惊。
重置定時(shí)器與停止定時(shí)器
了解重置定時(shí)器和使用 Stop()
停止定時(shí)器之間的區(qū)別非常重要唆途。
func CompareResetAndStop() {
timer := time.NewTimer(5 * time.Second)
fmt.Printf("time: %d, Timer created.\n", time.Now().Unix())
go func() {
<-timer.C
fmt.Printf("time: %d, Timer expired.\n", time.Now().Unix())
}()
time.Sleep(2 * time.Second)
timer.Reset(3 * time.Second)
fmt.Printf("time: %d, Timer reset.\n", time.Now().Unix())
time.Sleep(2 * time.Second)
timer.Stop()
fmt.Printf("time: %d, Timer stopped.\n", time.Now().Unix())
}
輸出為:
time: 1695183802, Timer created.
time: 1695183804, Timer reset.
time: 1695183806, Timer stopped.
在本例中富雅,我們創(chuàng)建了一個(gè)持續(xù)時(shí)間為 5 秒的計(jì)時(shí)器。2 秒后肛搬,我們使用 timer.Reset()
將計(jì)時(shí)器重置為 3 秒吹榴。之后,再過(guò) 2 秒滚婉,我們使用 timer.Stop()
停止計(jì)時(shí)器。重置定時(shí)器會(huì)改變其持續(xù)時(shí)間并重新開始倒計(jì)時(shí)帅刀,而停止定時(shí)器則會(huì)立即停止執(zhí)行让腹,無(wú)論剩余持續(xù)時(shí)間多長(zhǎng)。
帶 Ticker 的計(jì)時(shí)器
Go 提供了一種 Ticker
類型扣溺,它是一種專門的定時(shí)器骇窍,可在指定的時(shí)間間隔內(nèi)重復(fù)觸發(fā)。定時(shí)器可用于定期執(zhí)行任務(wù)锥余。
func Tick() {
ticker := time.NewTicker(1 * time.Second)
defer ticker.Stop()
go func() {
for range ticker.C {
fmt.Printf("time: %d, Ticker ticked!\n", time.Now().Unix())
}
}()
time.Sleep(5 * time.Second)
}
在本例中腹纳,我們使用 time.NewTicker()
創(chuàng)建了一個(gè)持續(xù)時(shí)間為 1 秒的 Ticker。然后驱犹,我們啟動(dòng)一個(gè) goroutine嘲恍,從 ticker.C
channel 接收值,每當(dāng)?shù)未鹇曧懫饡r(shí)雄驹,goroutine 就會(huì)發(fā)出一個(gè)值佃牛。在 goroutine 中,每次接收到一個(gè) tick 時(shí)医舆,我們都會(huì)打印 "Ticker ticked!"俘侠。調(diào)用 time.Sleep()
可以讓滴答滴答運(yùn)行 5 秒鐘,然后退出程序蔬将。
使用 Select 的超時(shí)
Go 的 select
語(yǔ)句允許在多個(gè)通道上執(zhí)行非阻塞操作爷速。這可以用來(lái)使用計(jì)時(shí)器實(shí)現(xiàn)超時(shí)。
func TimeOut() {
ch := make(chan string)
go func() {
time.Sleep(2 * time.Second)
ch <- "Operation completed."
}()
select {
case msg := <-ch:
fmt.Println(msg)
case <-time.After(1 * time.Second):
fmt.Println("Timeout reached.")
}
}
在本例中霞怀,我們創(chuàng)建了一個(gè) channel ch
惫东,并啟動(dòng)一個(gè) goroutine 來(lái)模擬耗時(shí) 2 秒的操作。我們使用 select
語(yǔ)句從 ch
接收信息里烦,或使用 time.After()
等待超時(shí)凿蒜。如果操作在 1 秒內(nèi)完成,則打印消息胁黑。否則废封,將執(zhí)行超時(shí)情況,并打印 "Timeout reached."丧蘸。
本文由mdnice多平臺(tái)發(fā)布