Ticker Or Sleep?定時執(zhí)行的新選擇
在寫 Python 的時候,如果想讓某個函數(shù)每 60 秒執(zhí)行一次,我們一般這樣寫代碼:
- import time
 - while True:
 - some_function()
 - time.sleep(60)
 
于是,我在寫 Golang 代碼的時候,也使用了這種方式:
- package main
 - import (
 - "fmt"
 - "time"
 - )
 - func someFunction() {
 - fmt.Println("我是某個函數(shù)")
 - }
 - func main() {
 - for {
 - someFunction()
 - time.Sleep(10 * time.Second)
 - }
 - }
 
今天在看同事的代碼時,發(fā)現(xiàn)他是這樣寫的:
- package main
 - import (
 - "fmt"
 - "time"
 - )
 - func someFunction() {
 - fmt.Println("我是某個函數(shù)")
 - }
 - func main() {
 - tikcer := time.NewTicker(10 * time.Second)
 - for {
 - <-tikcer.C
 - someFunction()
 - }
 - }
 
這種寫法,初看起來時跟time.Sleep沒什么區(qū)別,但是仔細一想,卻發(fā)現(xiàn)它有很多優(yōu)勢。
首先,NewTicker會在背后計時,時間到了以后,會向內(nèi)部的一個 channel 中推入當前的時間。然后繼續(xù)計時。所以,如果函數(shù)someFunction()執(zhí)行了3秒鐘。那么接下來過7秒就會繼續(xù)執(zhí)行。但如果使用time.Sleep,函數(shù)執(zhí)行完成以后,還要再等10秒鐘才會執(zhí)行。
其次,如果不啟動新的協(xié)程,那么當執(zhí)行到time.Sleep時,整個程序是卡住的,必須等待它結(jié)束了才能執(zhí)行后面的操作。但如果使用 NewTicker,那么在等待的時間,還可以做很多其他的事情。多個不同的定時器可以同時工作:
- package main
 - import (
 - "fmt"
 - "time"
 - )
 - func someFunction() {
 - fmt.Println("我是某個函數(shù)")
 - }
 - func anotherFunction() {
 - fmt.Println("另一個函數(shù)")
 - }
 - func thirdFunction() {
 - fmt.Println("第三個函數(shù)")
 - }
 - func main() {
 - tikcer1 := time.NewTicker(10 * time.Second)
 - tikcer2 := time.NewTicker(5 * time.Second)
 - tikcer3 := time.NewTicker(3 * time.Second)
 - for {
 - select {
 - case <-tikcer1.C:
 - someFunction()
 - case <-tikcer2.C:
 - anotherFunction()
 - case <-tikcer3.C:
 - thirdFunction()
 - }
 - }
 - }
 
這樣可以實現(xiàn),每3秒執(zhí)行 thirdFunction函數(shù),每5秒執(zhí)行anotherFunction,每10秒執(zhí)行一次someFunction。大家可以考慮一下,如何用 time.Sleep來實現(xiàn)這樣的功能。
注意每個函數(shù)都是獨立計時的,只要他們執(zhí)行的時間不超過他們間隔的時間,就不會互相影響。
除了全部用來計時外,我們還可以用來設置外部開關(guān),中斷一個協(xié)程。例如:
- package main
 - import (
 - "fmt"
 - "time"
 - )
 - func doSomething() {
 - fmt.Println("進行某些操作")
 - }
 - func someFunction(stop chan bool) {
 - fmt.Println("我是某個函數(shù)")
 - tikcer1 := time.NewTicker(10 * time.Second)
 - for {
 - select {
 - case <-tikcer1.C:
 - doSomething()
 - case <-stop:
 - return
 - }
 - }
 - }
 - func main() {
 - stop := make(chan bool)
 - go someFunction(stop)
 - //很多行代碼
 - //很多行代碼
 - //很多行代碼
 - stop <- true
 - //其他代碼
 - //其他代碼
 - }
 
在協(xié)程里面是一個10秒執(zhí)行一次的定時函數(shù)。但是我們可以在外面控制這個協(xié)程,從而隨時停止這個協(xié)程。
本文轉(zhuǎn)載自微信公眾號「未聞Code」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請聯(lián)系未聞Code公眾號。
















 
 
 


 
 
 
 