如何實(shí)現(xiàn)GolangCron定時(shí)任務(wù)

小編這次要給大家分享的是如何實(shí)現(xiàn)Golang Cron定時(shí)任務(wù),文章內(nèi)容豐富,感興趣的小伙伴可以來(lái)了解一下,希望大家閱讀完這篇文章之后能夠有所收獲。

10年積累的成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、外貿(mào)網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶(hù)對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶(hù)得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有沈丘免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。

開(kāi)門(mén)見(jiàn)山寫(xiě)一個(gè)

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")) // 為何要專(zhuān)門(mén)制定這個(gè)時(shí)間
      t1.Reset(time.Second * 10)
    }
  }
}

func main() {
  fmt.Println(strings.Repeat("START ", 15))
  CronTest()
  fmt.Println(strings.Repeat("END ", 15))
}

核心的定時(shí)器代碼就3行

c := cron.New()
c.AddFunc("* * * * * *", CronTask)
c.Start()

那后面那些代碼時(shí)作甚的?

一開(kāi)始看到示例代碼時(shí),有個(gè)疑惑,如代碼中注釋

t1 := time.NewTimer(time.Second * 10)

這里time.Second*10是干啥的? 是否可以寫(xiě)成*100呢, 改了后原來(lái)是可以的,那更疑惑了既然都行為啥還要寫(xiě)個(gè)這個(gè)?

還有后面的for-select-case也是一臉懵逼~~~~

運(yùn)行代碼,從結(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 ********  *******  *******

以上是運(yùn)行的片段,有兩大發(fā)現(xiàn)

  1. 有START START START。。。沒(méi)有END END END 。。。。:說(shuō)明了代碼在執(zhí)行時(shí)阻塞在定時(shí)器里,定時(shí)器沒(méi)有執(zhí)行完,永遠(yuǎn)不會(huì)執(zhí)行END
  2. Time now打出來(lái)的間隔正好是10s

哦,原來(lái)time.NewTimer是個(gè)定時(shí)器,當(dāng)這個(gè)時(shí)間間隔完了后再重新打開(kāi)一個(gè)。for-select-case 這一塊目的是阻塞流程,不讓程序結(jié)束。 理解對(duì)嗎

如果是這樣,去掉for-select-case 執(zhí)行第一個(gè)定時(shí)器時(shí)也可以停10s,是這樣嗎?試驗(yàn)下:屏蔽掉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

打臉了,看來(lái)阻塞主要靠for-select-case實(shí)現(xiàn),那原理是什么呢?

去掉t1.Reset效果咋樣呢?

t1 := time.NewTimer(time.Second * 10) // &#63;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, 運(yùn)行完第一個(gè)定時(shí)器10s, 非但沒(méi)聽(tīng),還直接執(zhí)行起來(lái)了,沒(méi)停了

for 循環(huán)里的print不是刷刷的一大片,而是和case命中時(shí)一期打,看來(lái)是時(shí)候了解下select-case的原理了

select case

按慣例先上個(gè)例子

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 語(yǔ)法

每個(gè)case都必須是個(gè)通信

如果一個(gè)通信可進(jìn)行它就執(zhí)行,其他被忽略

如果有多個(gè)case可執(zhí)行,就會(huì)隨機(jī)的選擇一個(gè)執(zhí)行

如果沒(méi)有case可執(zhí)行,如果如果有default,執(zhí)行default語(yǔ)句;否則就阻塞,直到有某個(gè)通信可行

這里還是有很多問(wèn)題, 單開(kāi)一節(jié)弄清楚 select語(yǔ)句

再回到一開(kāi)始的定時(shí)任務(wù)

回顧正題,定時(shí)原理解析

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)
    }
  }
  • 生成一個(gè)定時(shí)器t1, 執(zhí)行for循環(huán),一開(kāi)始定時(shí)時(shí)間(10s)未到, 也沒(méi)有阻塞任務(wù),它就阻塞在case中;
  • 定時(shí)時(shí)間到了,則執(zhí)行case中語(yǔ)句;
  • 然后又重新恢復(fù)定時(shí)時(shí)長(zhǎng)
  • 重新走for循環(huán),還是重復(fù)上面的故事

上面代碼中嘗試把case中的t1.Reset去掉,結(jié)果也是定時(shí)任務(wù)不同的執(zhí)行,原因是執(zhí)行case中的語(yǔ)句后,接著執(zhí)行for循環(huán),由于沒(méi)有新通信過(guò)來(lái)(case語(yǔ)句永遠(yuǎn)無(wú)法滿(mǎn)足),同時(shí)沒(méi)有default語(yǔ)句,所以同樣可以阻塞再次。

相比在case中t1 Reset, t1 Reset更靈活些,因?yàn)榭梢栽倜看沃匦聺M(mǎn)足case時(shí)做一些靈活的操作,比如跳出循環(huán),做一些統(tǒng)計(jì)打印等。

看完這篇關(guān)于如何實(shí)現(xiàn)Golang Cron定時(shí)任務(wù)的文章,如果覺(jué)得文章內(nèi)容寫(xiě)得不錯(cuò)的話,可以把它分享出去給更多人看到。

名稱(chēng)欄目:如何實(shí)現(xiàn)GolangCron定時(shí)任務(wù)
本文來(lái)源:http://muchs.cn/article42/ihsjhc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供ChatGPT、用戶(hù)體驗(yàn)、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站內(nèi)鏈、網(wǎng)站導(dǎo)航、App開(kāi)發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作