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

Golang定時(shí)器Timer與Ticker的使用詳解

 更新時(shí)間:2023年05月16日 17:02:12   作者:人艱不拆_zmc  
在 Go 里有很多種定時(shí)器的使用方法,像常規(guī)的 Timer、Ticker 對(duì)象,本文主要為大家介紹了Timer與Ticker的使用,感興趣的小伙伴可以了解一下

1、概述

在 Go 里有很多種定時(shí)器的使用方法,像常規(guī)的 Timer、Ticker 對(duì)象,以及經(jīng)常會(huì)看到的 time.After(d Duration) 和 time.Sleep(d Duration) 方法。以上這些定時(shí)器的使用方法都來自Golang 原生 time 包,使用time包可以用來執(zhí)行一些定時(shí)任務(wù)或者是周期性的任務(wù)。

2、定時(shí)器使用

2.1 Timer 相關(guān)

func NewTimer(d Duration) *Timer
func (t *Timer) Reset(d Duration) bool
func (t *Timer) Stop() bool
func After(d Duration) <-chan Time
func AfterFunc(d Duration, f func()) *Timer
 
//timer例子
func main() {
   timer := time.NewTimer(3 * time.Second)  //啟動(dòng)定時(shí)器,生產(chǎn)一個(gè)Timer對(duì)象
   select {
   case <-timer.C:
      fmt.Println("3秒執(zhí)行任務(wù)")
   }
   timer.Stop() // 不再使用了,結(jié)束它
}
 
//time.After例子
func main() {
   tChannel := time.After(3 * time.Second) // 其內(nèi)部其實(shí)是生成了一個(gè)Timer對(duì)象
   select {
   case <-tChannel:
      fmt.Println("3秒執(zhí)行任務(wù)")
   }
}
 
func main() {
  timer := time.NewTimer(3 * time.Second)
  for {
    timer.Reset(4 * time.Second) // 這樣來復(fù)用 timer 和修改執(zhí)行時(shí)間
    select {
    case <-timer.C:
      fmt.Println("每隔4秒執(zhí)行任務(wù)")
    }
  }
}

從上面可以看出來 Timer 允許再次被啟用,而 time.After 返回的是一個(gè) channel,將不可復(fù)用。

而且需要注意的是 time.After 本質(zhì)上是創(chuàng)建了一個(gè)新的 Timer 結(jié)構(gòu)體,只不過暴露出去的是結(jié)構(gòu)體里的 channel 字段而已。

因此如果在 for{...}里循環(huán)使用了 time.After,將會(huì)不斷的創(chuàng)建 Timer。如下的使用方法就會(huì)帶來性能問題:

錯(cuò)誤使用:

for 里的 time.After 將會(huì)不斷的創(chuàng)建 Timer 對(duì)象,雖然最終會(huì)回收,但是會(huì)造成無意義的cpu資源消耗

func main() {
   for {
      select {
      case <-time.After(3 * time.Second):
         fmt.Println("每隔3秒執(zhí)行一次")
      }
   }
}

正確使用:

func main() {
   timer := time.NewTimer(3 * time.Second)
   for {
      timer.Reset(3 * time.Second) // 這里復(fù)用了 timer
      select {
      case <-timer.C:
         fmt.Println("每隔3秒執(zhí)行一次")
      }
   }
}

2.2 Ticker 相關(guān)

這里的 Ticker 跟 Timer 的不同之處,就在于 Ticker 時(shí)間達(dá)到后不需要人為調(diào)用 Reset 方法,會(huì)自動(dòng)續(xù)期。

func NewTicker(d Duration) *Ticker
func Tick(d Duration) <-chan Time
func (t *Ticker) Stop()
func main() {
  ticker := time.NewTicker(3 * time.Second)
  for range ticker.C {
    fmt.Print("每隔3秒執(zhí)行任務(wù)")
  }
  ticker.Stop()
}

錯(cuò)誤使用:

func main() {
   for {
      select {
      case <-time.Tick(3 * time.Second): // 這里會(huì)不斷生成 ticker,而且 ticker 會(huì)進(jìn)行重新調(diào)度,造成泄漏
         fmt.Println("每隔3秒執(zhí)行一次")
      }
   }
} 

3、定時(shí)器使用示例

3.1 Ticker定時(shí)器

package main
import (
    "fmt"
    "time"
)
func main() {
    // Ticker 包含一個(gè)通道字段C,每隔時(shí)間段 d 就向該通道發(fā)送當(dāng)時(shí)系統(tǒng)時(shí)間。
    // 它會(huì)調(diào)整時(shí)間間隔或者丟棄 tick 信息以適應(yīng)反應(yīng)慢的接收者。
    // 如果d <= 0會(huì)觸發(fā)panic。關(guān)閉該 Ticker 可以釋放相關(guān)資源。
    ticker1 := time.NewTicker(5 * time.Second)
    // 一定要調(diào)用Stop(),回收資源
    defer ticker1.Stop()
    go func(t *time.Ticker) {
        for {
            // 每5秒中從chan t.C 中讀取一次
            <-t.C
            fmt.Println("Ticker:", time.Now().Format("2006-01-02 15:04:05"))
        }
    }(ticker1)
    time.Sleep(30 * time.Second)
    fmt.Println("ok")
}  

執(zhí)行結(jié)果:

Ticker: 2022-01-18 13:39:30
Ticker: 2022-01-18 13:39:35
Ticker: 2022-01-18 13:39:40
Ticker: 2022-01-18 13:39:45
Ticker: 2022-01-18 13:39:50
ok
Ticker: 2022-01-18 13:39:55

可以看到每次執(zhí)行的時(shí)間間隔都是一樣的,由于main線程結(jié)束導(dǎo)致程序結(jié)束。

3.2 Timer定時(shí)器

package main
 
import (
    "fmt"
    "time"
)
 
func main() {
 
    // NewTimer 創(chuàng)建一個(gè) Timer,它會(huì)在最少過去時(shí)間段 d 后到期,向其自身的 C 字段發(fā)送當(dāng)時(shí)的時(shí)間
    timer1 := time.NewTimer(5 * time.Second)
 
    fmt.Println("開始時(shí)間:", time.Now().Format("2006-01-02 15:04:05"))
    go func(t *time.Timer) {
        times := 0
        for {
            <-t.C
            fmt.Println("timer", time.Now().Format("2006-01-02 15:04:05"))
 
            // 從t.C中獲取數(shù)據(jù),此時(shí)time.Timer定時(shí)器結(jié)束。如果想再次調(diào)用定時(shí)器,只能通過調(diào)用 Reset() 函數(shù)來執(zhí)行
            // Reset 使 t 重新開始計(jì)時(shí),(本方法返回后再)等待時(shí)間段 d 過去后到期。
            // 如果調(diào)用時(shí) t 還在等待中會(huì)返回真;如果 t已經(jīng)到期或者被停止了會(huì)返回假。
            times++
            // 調(diào)用 reset 重發(fā)數(shù)據(jù)到chan C
            fmt.Println("調(diào)用 reset 重新設(shè)置一次timer定時(shí)器,并將時(shí)間修改為2秒")
            t.Reset(2 * time.Second)
            if times > 3 {
                fmt.Println("調(diào)用 stop 停止定時(shí)器")
                t.Stop()
            }
        }
    }(timer1)
 
    time.Sleep(30 * time.Second)
    fmt.Println("結(jié)束時(shí)間:", time.Now().Format("2006-01-02 15:04:05"))
    fmt.Println("ok")
}

執(zhí)行結(jié)果:

開始時(shí)間: 2022-01-18 13:25:43
timer 2022-01-18 13:25:48
調(diào)用 reset 重新設(shè)置一次timer定時(shí)器,并將時(shí)間修改為2秒
timer 2022-01-18 13:25:50
調(diào)用 reset 重新設(shè)置一次timer定時(shí)器,并將時(shí)間修改為2秒
timer 2022-01-18 13:25:52
調(diào)用 reset 重新設(shè)置一次timer定時(shí)器,并將時(shí)間修改為2秒
timer 2022-01-18 13:25:54
調(diào)用 reset 重新設(shè)置一次timer定時(shí)器,并將時(shí)間修改為2秒
調(diào)用 stop 停止定時(shí)器
結(jié)束時(shí)間: 2022-01-18 13:26:13
ok

可以看到,第一次執(zhí)行時(shí)間為5秒以后。然后通過調(diào)用 time.Reset() 方法再次激活定時(shí)器,定時(shí)時(shí)間為2秒,最后通過調(diào)用 time.Stop() 把前面的定時(shí)器取消掉。

4、總結(jié)

ticker定時(shí)器表示每隔一段時(shí)間就執(zhí)行一次,一般可執(zhí)行多次。

timer定時(shí)器表示在一段時(shí)間后執(zhí)行,默認(rèn)情況下只執(zhí)行一次,如果想再次執(zhí)行的話,每次都需要調(diào)用 time.Reset() 方法,此時(shí)效果類似ticker定時(shí)器。同時(shí)也可以調(diào)用 Stop() 方法取消定時(shí)器

timer定時(shí)器比ticker定時(shí)器多一個(gè) Reset() 方法,兩者都有 Stop() 方法,表示停止定時(shí)器,底層都調(diào)用了stopTimer() 函數(shù)。

除了上面的定時(shí)器外,Go 里的 time.Sleep 也起到了類似一次性使用的定時(shí)功能。只不過 time.Sleep 使用了系統(tǒng)調(diào)用。而像上面的定時(shí)器更多的是靠 Go 的調(diào)度行為來實(shí)現(xiàn)。

無論哪種計(jì)時(shí)器,.C 都是一個(gè) chan Time 類型且容量為 1 的單向 Channel,當(dāng)有超過 1 個(gè)數(shù)據(jù)的時(shí)候便會(huì)被阻塞,以此保證不會(huì)被觸發(fā)多次。

到此這篇關(guān)于Golang定時(shí)器Timer與Ticker的使用詳解的文章就介紹到這了,更多相關(guān)Golang定時(shí)器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 一文詳解Go語(yǔ)言中的有限狀態(tài)機(jī)FSM

    一文詳解Go語(yǔ)言中的有限狀態(tài)機(jī)FSM

    有限狀態(tài)機(jī)(Finite?State?Machine,F(xiàn)SM)是一種數(shù)學(xué)模型,用于描述系統(tǒng)在不同狀態(tài)下的行為和轉(zhuǎn)移條件。本文主要來和大家簡(jiǎn)單講講Go語(yǔ)言中的有限狀態(tài)機(jī)FSM的使用,需要的可以參考一下
    2023-04-04
  • Go語(yǔ)言按字節(jié)截取字符串的方法

    Go語(yǔ)言按字節(jié)截取字符串的方法

    這篇文章主要介紹了Go語(yǔ)言按字節(jié)截取字符串的方法,涉及Go語(yǔ)言操作字符串的技巧,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2015-02-02
  • 使用Go語(yǔ)言與MQTT進(jìn)行通信的示例代碼

    使用Go語(yǔ)言與MQTT進(jìn)行通信的示例代碼

    本文介紹了如何使用 Go 編程語(yǔ)言與 MQTT(Message Queuing Telemetry Transport)進(jìn)行通信,MQTT 是一種輕量級(jí)的消息傳輸協(xié)議,廣泛應(yīng)用于物聯(lián)網(wǎng)和實(shí)時(shí)通信場(chǎng)景,通過本文的指導(dǎo),您將學(xué)習(xí)如何使用 Go 語(yǔ)言創(chuàng)建 MQTT 客戶端,進(jìn)行消息的發(fā)布和訂閱,需要的朋友可以參考下
    2023-12-12
  • Go語(yǔ)言中獲取函數(shù)實(shí)體的四種方法小結(jié)

    Go語(yǔ)言中獲取函數(shù)實(shí)體的四種方法小結(jié)

    本文主要介紹了Go語(yǔ)言中獲取函數(shù)實(shí)體的四種方法,包括反射獲取地址、runtime獲取名稱、函數(shù)變量傳遞實(shí)體及包內(nèi)函數(shù)解析,具有一定的參考價(jià)值,感興趣的可以了解一下
    2025-05-05
  • gin項(xiàng)目部署到服務(wù)器并后臺(tái)啟動(dòng)的步驟

    gin項(xiàng)目部署到服務(wù)器并后臺(tái)啟動(dòng)的步驟

    本文主要介紹了gin項(xiàng)目部署到服務(wù)器并后臺(tái)啟動(dòng)的步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Go語(yǔ)言CSP并發(fā)模型實(shí)現(xiàn)MPG

    Go語(yǔ)言CSP并發(fā)模型實(shí)現(xiàn)MPG

    這篇文章主要為大家介紹了Go語(yǔ)言CSP并發(fā)模型實(shí)現(xiàn)MPG圖文詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • 精通Go語(yǔ)言日志記錄高效日志管理

    精通Go語(yǔ)言日志記錄高效日志管理

    本文將深入探討 Go 語(yǔ)言中的日志記錄,包括 Go 的標(biāo)準(zhǔn)日志庫(kù)的使用、流行的第三方日志庫(kù)以及如何在實(shí)際項(xiàng)目中實(shí)現(xiàn)有效的日志管理
    2023-11-11
  • 使用Go初始化Struct的方法詳解

    使用Go初始化Struct的方法詳解

    面向?qū)ο缶幊陶Z(yǔ)言最基礎(chǔ)的概念就是類(class),不過Go語(yǔ)言并沒有類的概念,所以使用Go語(yǔ)言開發(fā)時(shí),我們一般會(huì)用struct(結(jié)構(gòu)體)來模擬面向?qū)ο笾械念?下面我們來介紹幾種創(chuàng)建struct類型變量的方法,需要的朋友可以參考下
    2024-01-01
  • 詳解Go語(yǔ)言變量作用域

    詳解Go語(yǔ)言變量作用域

    這篇文章主要介紹了Go 語(yǔ)言變量作用域的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)使用go語(yǔ)言,感興趣的朋友可以了解下
    2021-03-03
  • Go錯(cuò)誤和異常CGO?fallthrough處理教程詳解

    Go錯(cuò)誤和異常CGO?fallthrough處理教程詳解

    這篇文章主要為大家介紹了Go錯(cuò)誤和異常CGO?fallthrough使用教程詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-08-08

最新評(píng)論

清镇市| 宁国市| 济阳县| 佳木斯市| 周宁县| 孙吴县| 石河子市| 无为县| 丰都县| 神木县| 齐齐哈尔市| 安国市| 巴林左旗| 石城县| 遵义市| 华亭县| 德惠市| 静海县| 康保县| 工布江达县| 涪陵区| 漳州市| 江阴市| 刚察县| 师宗县| 牟定县| 五指山市| 闽清县| 腾冲县| 阿拉善右旗| 郑州市| 兴山县| 偏关县| 海原县| 宣汉县| 昌平区| 法库县| 于都县| 蕉岭县| 报价| 高清|