小編這次要給大家分享的是如何實現(xiàn)Golang Cron定時任務(wù),文章內(nèi)容豐富,感興趣的小伙伴可以來了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。
10年積累的成都網(wǎng)站設(shè)計、成都做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認識你,你也不認識我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有沈丘免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。
開門見山寫一個
package main import ( "fmt" "github.com/robfig/cron" "log" "strings" "time" ) func CronTask() { log.Println("******** ******* *******") } func CronTest() { log.Println("Starting Cron...") c := cron.New() c.AddFunc("* * * * * *", CronTask) //2 * * * * *, 2 表示每分鐘的第2s執(zhí)行一次 c.Start() t1 := time.NewTimer(time.Second * 10) // ?time.Second * 10 啥意思? *100行嗎? for { select { case <-t1.C: fmt.Println("Time now:", time.Now().Format("2006-01-02 15:04:05")) // 為何要專門制定這個時間 t1.Reset(time.Second * 10) } } } func main() { fmt.Println(strings.Repeat("START ", 15)) CronTest() fmt.Println(strings.Repeat("END ", 15)) }
核心的定時器代碼就3行
c := cron.New() c.AddFunc("* * * * * *", CronTask) c.Start()
那后面那些代碼時作甚的?
一開始看到示例代碼時,有個疑惑,如代碼中注釋
t1 := time.NewTimer(time.Second * 10)
這里time.Second*10是干啥的? 是否可以寫成*100呢, 改了后原來是可以的,那更疑惑了既然都行為啥還要寫個這個?
還有后面的for-select-case也是一臉懵逼~~~~
運行代碼,從結(jié)果反推下原理吧,一次執(zhí)行結(jié)果
START START START START START START START START START START START START START START START
2020/05/01 07:38:07 Starting Cron...
2020/05/01 07:38:08 ******** ******* *******
2020/05/01 07:38:09 ******** ******* *******
2020/05/01 07:38:10 ******** ******* *******
2020/05/01 07:38:11 ******** ******* *******
2020/05/01 07:38:12 ******** ******* *******
2020/05/01 07:38:13 ******** ******* *******
2020/05/01 07:38:14 ******** ******* *******
2020/05/01 07:38:15 ******** ******* *******
2020/05/01 07:38:16 ******** ******* *******
2020/05/01 07:38:17 ******** ******* *******
Time now: 2020-05-01 07:38:17
2020/05/01 07:38:18 ******** ******* *******
2020/05/01 07:38:19 ******** ******* *******
2020/05/01 07:38:20 ******** ******* *******
2020/05/01 07:38:21 ******** ******* *******
2020/05/01 07:38:22 ******** ******* *******
2020/05/01 07:38:23 ******** ******* *******
2020/05/01 07:38:24 ******** ******* *******
2020/05/01 07:38:25 ******** ******* *******
2020/05/01 07:38:26 ******** ******* *******
2020/05/01 07:38:27 ******** ******* *******
Time now: 2020-05-01 07:38:27
2020/05/01 07:38:28 ******** ******* *******
以上是運行的片段,有兩大發(fā)現(xiàn)
哦,原來time.NewTimer是個定時器,當這個時間間隔完了后再重新打開一個。for-select-case 這一塊目的是阻塞流程,不讓程序結(jié)束。 理解對嗎
如果是這樣,去掉for-select-case 執(zhí)行第一個定時器時也可以停10s,是這樣嗎?試驗下:屏蔽掉for-select-case, 輸出
START START START START START START START START START START START START START START START
2020/05/01 07:56:22 Starting Cron...
END END END END END END END END END END END END END END END
打臉了,看來阻塞主要靠for-select-case實現(xiàn),那原理是什么呢?
去掉t1.Reset效果咋樣呢?
t1 := time.NewTimer(time.Second * 10) // ?time.Second * 10 啥意思? *100行嗎? for { fmt.Println("hihihihi") select { case <-t1.C: fmt.Println("hello") } }
輸出
START START START START START START START START START START START START START START START
2020/05/01 08:12:21 Starting Cron...
hihihihi
2020/05/01 08:12:22 ******** ******* *******
2020/05/01 08:12:23 ******** ******* *******
2020/05/01 08:12:24 ******** ******* *******
2020/05/01 08:12:25 ******** ******* *******
2020/05/01 08:12:26 ******** ******* *******
2020/05/01 08:12:27 ******** ******* *******
2020/05/01 08:12:28 ******** ******* *******
2020/05/01 08:12:29 ******** ******* *******
2020/05/01 08:12:30 ******** ******* *******
2020/05/01 08:12:31 ******** ******* *******
hello
hihihihi
2020/05/01 08:12:32 ******** ******* *******
2020/05/01 08:12:33 ******** ******* *******
2020/05/01 08:12:34 ******** ******* *******
2020/05/01 08:12:35 ******** ******* *******
2020/05/01 08:12:36 ******** ******* *******
更蒙了,去掉reset, 運行完第一個定時器10s, 非但沒聽,還直接執(zhí)行起來了,沒停了
for 循環(huán)里的print不是刷刷的一大片,而是和case命中時一期打,看來是時候了解下select-case的原理了
select case
按慣例先上個例子
package main import ( "fmt" "strings" ) func SelectTest() { intChan := make(chan int, 1) stringChan := make(chan string, 1) intChan <- 123456 stringChan <- "hello" select { case value := <-intChan: fmt.Println(value) case value := <- stringChan: fmt.Println(value) } } func main() { fmt.Println(strings.Repeat("START ", 15)) SelectTest() fmt.Println(strings.Repeat("END ", 15)) }
執(zhí)行多次可以看到,輸出的結(jié)果是 123456、"hello"不定
select 語法
每個case都必須是個通信
如果一個通信可進行它就執(zhí)行,其他被忽略
如果有多個case可執(zhí)行,就會隨機的選擇一個執(zhí)行
如果沒有case可執(zhí)行,如果如果有default,執(zhí)行default語句;否則就阻塞,直到有某個通信可行
這里還是有很多問題, 單開一節(jié)弄清楚 select語句
再回到一開始的定時任務(wù)
回顧正題,定時原理解析
t1 := time.NewTimer(time.Second * 10) for { select { case <-t1.C: fmt.Println("Time now:", time.Now().Format("2006-01-02 15:04:05")) t1.Reset(time.Second * 10) } }
上面代碼中嘗試把case中的t1.Reset去掉,結(jié)果也是定時任務(wù)不同的執(zhí)行,原因是執(zhí)行case中的語句后,接著執(zhí)行for循環(huán),由于沒有新通信過來(case語句永遠無法滿足),同時沒有default語句,所以同樣可以阻塞再次。
相比在case中t1 Reset, t1 Reset更靈活些,因為可以再每次重新滿足case時做一些靈活的操作,比如跳出循環(huán),做一些統(tǒng)計打印等。
看完這篇關(guān)于如何實現(xiàn)Golang Cron定時任務(wù)的文章,如果覺得文章內(nèi)容寫得不錯的話,可以把它分享出去給更多人看到。
名稱欄目:如何實現(xiàn)GolangCron定時任務(wù)
本文來源:http://chinadenli.net/article42/ihsjhc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、用戶體驗、網(wǎng)頁設(shè)計公司、網(wǎng)站內(nèi)鏈、網(wǎng)站導(dǎo)航、App開發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)