<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Go定時(shí)器的三種實(shí)現(xiàn)方式

          共 2001字,需瀏覽 5分鐘

           ·

          2022-12-22 10:16

          很多時(shí)候需要周期性的執(zhí)行某些操作,就需要用到定時(shí)器。定時(shí)器有三種思路。

          Sleep

          使用休眠,讓當(dāng)前Goroutine休眠一定的時(shí)間來(lái)實(shí)現(xiàn)定時(shí)的效果,缺點(diǎn)是程序執(zhí)行速度不均勻,導(dǎo)致定時(shí)周期不均勻。

          for{
            fmt.Println(time.Now())
            time.Sleep(time.Second*1)
           }

          Timer

          Go 語(yǔ)言的內(nèi)置包,指定一個(gè)時(shí)間開始計(jì)時(shí),時(shí)間到之后會(huì)向外發(fā)送通知,發(fā)送通知的方式就是使用<-chan Time 返回內(nèi)容。

          第一種方式,直接在需要等待處使用,效果和Sleep一樣,一使用就卡在那了內(nèi)部就是使用了Timer

           fmt.Println(time.Now())
           <-time.After(1*time.Second)
           fmt.Println(time.Now())

          也可以把他拆分開,在任意地方進(jìn)行等待

           timer := time.NewTimer(1 * time.Second)
           <-timer.C
           fmt.Println(time.Now())

          但是以上只是做到延遲一次性執(zhí)行,我們來(lái)改造一下,把他變成定時(shí)器。

              done := make(chan struct{})
           timer := time.NewTimer(1 * time.Second)
           go func() {
            for {
             select {
             case <-timer.C:
              fmt.Println(time.Now())
              timer.Reset(1 * time.Second)
             case <-done:
              return
             }
            }
           }()
           <-time.After(5*time.Second + time.Millisecond*100)
           done <- struct{}{}
          • 定義子Goroutine的目的是為了防止形成死鎖,讓定時(shí)器最終能退出,在實(shí)際項(xiàng)目中可能需要一個(gè)永久運(yùn)行的定時(shí)器,一般為了不影響項(xiàng)目主邏輯也會(huì)這樣定義。如果你的項(xiàng)目就是定時(shí)任務(wù),我建議也這么寫,這樣可以注冊(cè)很多個(gè)定時(shí)器互不影響。
          • done是為了判斷執(zhí)行是否結(jié)束,防止主Goroutine提前退出。
          • 這個(gè)示例只有兩個(gè)case,實(shí)戰(zhàn)中如果有加其他case需要給每個(gè)case內(nèi)都做一次Reset,保證重置定時(shí)器。

          Ticker

          相比上述使用延遲執(zhí)行功能實(shí)現(xiàn)的定時(shí)器,Ticker 本身就是一個(gè)定時(shí)器(內(nèi)部封裝了Timer),我們使用起來(lái)就非常簡(jiǎn)單。

          ticker := time.NewTicker(1 * time.Second)
           go func() {
            for {
             <-ticker.C
             fmt.Println(time.Now())
            }
           }()
           <-time.After(5 * time.Second + time.Millisecond*100)
           ticker.Stop()

          在select 一節(jié)中講述的官方超時(shí)控制方案非常的實(shí)用,也是使用的此函數(shù)。還使用到timer.Stoptimer.Reset這兩個(gè)內(nèi)置函數(shù)這里就不展開講解了,建議進(jìn)行復(fù)習(xí)。

          小結(jié)

          定時(shí)器一般用來(lái)周期性執(zhí)行任務(wù),比如定時(shí)同步數(shù)據(jù)、計(jì)算報(bào)表、發(fā)送通知。

          • time.Sleep 使用休眠,讓當(dāng)前goroutine休眠一定的時(shí)間來(lái)實(shí)現(xiàn)定時(shí)的效果,缺點(diǎn)是內(nèi)部邏輯執(zhí)行的速度會(huì)影響到定時(shí)器的時(shí)間差,無(wú)法做到精確間隔。
          • Timer 類似于Sleep的延遲處理,通過(guò)channel來(lái)獲得通知,也可以改造成定時(shí)器。因?yàn)槭茄舆t處理,所以要記得重置時(shí)間來(lái)實(shí)現(xiàn)定時(shí)執(zhí)行的效果。
          • Ticker 現(xiàn)成的定時(shí)器,內(nèi)部也是封裝了 Timer

          瀏覽 58
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产一线视频在线观看 | 国产女孩骚逼AV重口免费大全 | 人人操国产高清使劲操91 | 精品成人午夜 | 亚洲成人A片 |