最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Golang Cron 定時任務(wù)的實現(xiàn)示例

 更新時間:2020年05月02日 10:38:34   作者:jihite  
這篇文章主要介紹了Golang Cron 定時任務(wù)的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

開門見山寫一個

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)

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

哦,原來time.NewTimer是個定時器,當(dāng)這個時間間隔完了后再重新打開一個。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都必須是個通信

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

如果有多個case可執(zhí)行,就會隨機(jī)的選擇一個執(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)
    }
  }
  • 生成一個定時器t1, 執(zhí)行for循環(huán),一開始定時時間(10s)未到, 也沒有阻塞任務(wù),它就阻塞在case中;
  • 定時時間到了,則執(zhí)行case中語句;
  • 然后又重新恢復(fù)定時時長
  • 重新走for循環(huán),還是重復(fù)上面的故事

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

相比在case中t1 Reset, t1 Reset更靈活些,因為可以再每次重新滿足case時做一些靈活的操作,比如跳出循環(huán),做一些統(tǒng)計打印等。

 到此這篇關(guān)于Golang Cron 定時任務(wù)的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)Golang Cron 定時任務(wù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Go語言使用defer+recover解決panic導(dǎo)致程序崩潰的問題

    Go語言使用defer+recover解決panic導(dǎo)致程序崩潰的問題

    如果協(xié)程出現(xiàn)了panic,就會造成程序的崩潰,這時可以在goroutine中使用recover來捕獲panic,進(jìn)行處理,本文就詳細(xì)的介紹一下,感興趣的可以了解一下
    2021-09-09
  • 讓Go反射變快的方法實例探究

    讓Go反射變快的方法實例探究

    反射允許你在運行時獲得有關(guān) Go 類型的信息,如果你曾經(jīng)愚蠢地嘗試編寫 json.Unmarshal 之類的新版本,本文將探討的就是如何使用反射來填充結(jié)構(gòu)體值
    2024-01-01
  • 淺析Go語言中的棧和先進(jìn)先出原則

    淺析Go語言中的棧和先進(jìn)先出原則

    這篇文章主要來和大家探討一樣如何在Go語言中實現(xiàn)和使用堆棧,以及堆棧如何遵循先進(jìn)先出 (FIFO) 原則,文中的示例代碼簡潔易懂,需要的可以參考一下
    2023-07-07
  • 使用Go語言構(gòu)建高效的二叉搜索樹聯(lián)系簿

    使用Go語言構(gòu)建高效的二叉搜索樹聯(lián)系簿

    樹是一種重要的數(shù)據(jù)結(jié)構(gòu),而二叉搜索樹(BST)則是樹的一種常見形式,在本文中,我們將學(xué)習(xí)如何構(gòu)建一個高效的二叉搜索樹聯(lián)系簿,感興趣的可以了解下
    2024-01-01
  • golang的HTTP基本認(rèn)證機(jī)制實例詳解

    golang的HTTP基本認(rèn)證機(jī)制實例詳解

    這篇文章主要介紹了golang的HTTP基本認(rèn)證機(jī)制,結(jié)合實例形式較為詳細(xì)的分析了HTTP請求響應(yīng)的過程及認(rèn)證機(jī)制實現(xiàn)技巧,需要的朋友可以參考下
    2016-07-07
  • Go 語言入門學(xué)習(xí)之正則表達(dá)式

    Go 語言入門學(xué)習(xí)之正則表達(dá)式

    這篇文章主要介紹了Go 語言入門學(xué)習(xí)之正則表達(dá)式,文章基于GO語言的相關(guān)資料展開詳細(xì)內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-04-04
  • 讓go程序以后臺進(jìn)程或daemon方式運行方法探究

    讓go程序以后臺進(jìn)程或daemon方式運行方法探究

    本文探討了如何通過Go代碼實現(xiàn)在后臺運行的程序,最近我用Go語言開發(fā)了一個WebSocket服務(wù),我希望它能在后臺運行,并在異常退出時自動重新啟動,我的整體思路是將程序轉(zhuǎn)為后臺進(jìn)程,也就是守護(hù)進(jìn)程(daemon)
    2024-01-01
  • 詳解如何使用pprof簡單檢測和修復(fù)Go語言中的內(nèi)存泄漏

    詳解如何使用pprof簡單檢測和修復(fù)Go語言中的內(nèi)存泄漏

    雖然?Go?有自動垃圾回收(GC),它能回收不再被使用的內(nèi)存,但這并不意味著?Go?程序中不會發(fā)生內(nèi)存泄漏,下面我們就來看看如何使用pprof進(jìn)行檢測和修復(fù)Go語言中的內(nèi)存泄漏吧
    2025-01-01
  • golang通過反射設(shè)置結(jié)構(gòu)體變量的值

    golang通過反射設(shè)置結(jié)構(gòu)體變量的值

    這篇文章主要介紹了golang通過反射設(shè)置結(jié)構(gòu)體變量的值操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • Golang極簡入門教程(三):并發(fā)支持

    Golang極簡入門教程(三):并發(fā)支持

    這篇文章主要介紹了Golang極簡入門教程(三):并發(fā)支持,本文講解了goroutine線程、channel 操作符等內(nèi)容,需要的朋友可以參考下
    2014-10-10

最新評論

双柏县| 舒兰市| 定日县| 团风县| 马龙县| 清流县| 嵩明县| 松桃| 八宿县| 浦县| 顺平县| 通榆县| 元阳县| 永和县| 洛川县| 亳州市| 磐安县| 会理县| 沧源| 金门县| 永嘉县| 兴山县| 博白县| 广水市| 平潭县| 钦州市| 松阳县| 师宗县| 杨浦区| 西华县| 霍城县| 平定县| 林周县| 安阳县| 化州市| 翁源县| 博兴县| 马公市| 阳谷县| 镇巴县| 玉溪市|