欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

golang 一次性定時器Timer用法及實現(xiàn)原理詳解

 更新時間:2022年08月25日 09:56:37   作者:yi個俗人  
這篇文章主要為大家介紹了golang 一次性定時器Timer用法及實現(xiàn)原理詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

前言

定時器在Go語言應用中使用非常廣泛,Go語言的標準庫里提供兩種類型的計時器,一種是一次性的定時器Timer,另外一種是周期性的定時Ticker。本文主要來看一下Timer的用法和實現(xiàn)原理,需要的朋友可以參考以下內(nèi)容,希望對大家有幫助。

Timer

Timer是一種單一事件的定時器,即經(jīng)過指定的時間后觸發(fā)一個事件,因為Timer只執(zhí)行一次就結束,所以稱為單一事件,這個事件通過其本身提供的channel進行通知觸發(fā)。

timer結構體

通過src/time.sleep.go:Timer定義了Timer數(shù)據(jù)結構:

// Timer代表一次定時,時間到達后僅執(zhí)行一個事件。
type Timer struct {
    C <-chan Time
    r runtimeTimer
}

它提供了一個channel,在定時時間到達之前,沒有數(shù)據(jù)寫入timer.C會一直阻塞,直到時間到達,向channel寫入系統(tǒng)時間,阻塞解除,可以從中讀取數(shù)據(jù),這就是一個事件。

創(chuàng)建定時器

func NewTimer(d Duration) *Timer

通過上面方法指定一個事件即可創(chuàng)建一個Timer,Timer一經(jīng)創(chuàng)建便開始計時,不需要額外的啟動命令。

示例:

func main()  {
	timer := time.NewTimer(time.Second * 5) //設置超時時間5s
	&lt;- timer.C
	fmt.Println("Time out!")
}

停止定時器

Timer創(chuàng)建后可以隨時停止,停止計時器的方法如下:

func (t *Timer) Stop() bool

其返回值代表定時器有沒有超時:

  • true:定時器超時前停止,后續(xù)不會再有事件發(fā)送。
  • false:定時器超時后停止。

示例:

func main()  {
	timer := time.NewTimer(time.Second * 5) //設置超時時間5s
    timer.Stop()
}

重置定時器

已經(jīng)過期的定時器或者已停止的定時器,可以通過重置動作重新激活,方法如下:

func (t *Timer) Reset(d Duration) bool

重置的動作本質(zhì)上是先停掉定時器,再啟動,其返回值也即是停掉計時器的返回值。

func main()  {
	timer := time.NewTimer(time.Second * 5)
	&lt;- timer.C
	fmt.Println("Time out!")
	timer.Stop() 
	timer.Reset(time.Second*3)  // 重置定時器
}

實現(xiàn)原理

每個Go應用程序都有一個協(xié)程專門負責管理所有的Timer,這個協(xié)程負責監(jiān)控Timer是否過期,過期后執(zhí)行一個預定義的動作,這個動作對于Timer而言就是發(fā)送當前時間到管道中。

數(shù)據(jù)結構

type Timer struct {
    C <-chan Time
    r runtimeTimer
}

Timer只有兩個成員:

  • C:channel,上層應用根據(jù)此管道接收事件;
  • r:runtimeTimer定時器,該定時器即系統(tǒng)管理的定時器,上層應用不可見。

runtimeTimer

任務的載體,用于監(jiān)控定時任務,每創(chuàng)建一個Timer就創(chuàng)建一個runtimeTimer變量,然后把它交給系統(tǒng)進行監(jiān)控,我們通過設置runtimeTimer過期后的行為來達到定時的目的。

源碼包src/time/sleep.go:runtimeTimer定義了其數(shù)據(jù)結構:

type runtimeTimer struct {
    tb uintptr                          // 存儲當前定時器的數(shù)組地址
    i  int                              // 存儲當前定時器的數(shù)組下標
    when   int64                        // 當前定時器觸發(fā)時間
    period int64                        // 當前定時器周期觸發(fā)間隔
    f      func(interface{}, uintptr)   // 定時器觸發(fā)時執(zhí)行的函數(shù)
    arg    interface{}                  // 定時器觸發(fā)時執(zhí)行函數(shù)傳遞的參數(shù)一
    seq    uintptr                      // 定時器觸發(fā)時執(zhí)行函數(shù)傳遞的參數(shù)二(該參數(shù)只在網(wǎng)絡收發(fā)場景下使用)
}

創(chuàng)建Timer

源碼實現(xiàn):

func NewTimer(d Duration) *Timer {
    c := make(chan Time, 1)  // 創(chuàng)建一個管道
    t := &Timer{ // 構造Timer數(shù)據(jù)結構
        C: c,               // 新創(chuàng)建的管道
        r: runtimeTimer{
            when: when(d),  // 觸發(fā)時間
            f:    sendTime, // 觸發(fā)后執(zhí)行函數(shù)sendTime
            arg:  c,        // 觸發(fā)后執(zhí)行函數(shù)sendTime時附帶的參數(shù)
        },
    }
    startTimer(&t.r) // 此處啟動定時器,只是把runtimeTimer放到系統(tǒng)協(xié)程的堆中,由系統(tǒng)協(xié)程維護
    return t
}
  • NewTimer()只是構造了一個Timer,然后把Timer.r通過startTimer()交給系統(tǒng)協(xié)程維護。
  • C 是一個帶1個容量的chan,這樣做有什么好處呢,原因是chan 無緩沖發(fā)送數(shù)據(jù)就會阻塞,阻塞系統(tǒng)協(xié)程,這顯然是不行的。
  • 回調(diào)函數(shù)設置為sendTime,執(zhí)行參數(shù)為channel,sendTime就是到點往C 里面發(fā)送當前時間的函數(shù)

sendTime實現(xiàn):

//c interface{} 就是NewTimer 賦值的參數(shù),就是channel
func sendTime(c interface{}, seq uintptr) {
    select {
    case c.(chan Time) <- Now(): //寫不進去的話,C 已滿,走default 分支
    default:
    }
}

停止Timer

停止Timer,就是把Timer從系統(tǒng)協(xié)程中移除。函數(shù)主要實現(xiàn)如下:

func (t *Timer) Stop() bool {
    return stopTimer(&t.r)
}

stopTimer()即通知系統(tǒng)協(xié)程把該Timer移除,即不再監(jiān)控。系統(tǒng)協(xié)程只是移除Timer并不會關閉管道,以避免用戶協(xié)程讀取錯誤。

重置Timer

重置Timer時會先把timer從系統(tǒng)協(xié)程中刪除,修改新的時間后重新添加到系統(tǒng)協(xié)程中。

func (t *Timer) Reset(d Duration) bool {
    w := when(d)
    active := stopTimer(&t.r)
    t.r.when = w
    startTimer(&t.r)
    return active
}

以上就是golang 一次性定時器Timer用法及實現(xiàn)原理詳解的詳細內(nèi)容,更多關于go 一次性定時器Timer的資料請關注腳本之家其它相關文章!

相關文章

  • golang 解析word文檔操作

    golang 解析word文檔操作

    這篇文章主要介紹了golang 解析word文檔操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Golang多模塊開發(fā)的詳細過程

    Golang多模塊開發(fā)的詳細過程

    這篇文章主要給大家介紹了關于Golang多模塊開發(fā)的詳細過程,文中通過實例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2023-02-02
  • Go中groutine通信與context控制實例詳解

    Go中groutine通信與context控制實例詳解

    隨著context包的引入,標準庫中很多接口因此加上了context參數(shù),下面這篇文章主要給大家介紹了關于Go中groutine通信與context控制的相關資料,需要的朋友可以參考下
    2022-02-02
  • golang常用庫之配置文件解析庫-viper使用詳解

    golang常用庫之配置文件解析庫-viper使用詳解

    viper 配置管理解析庫,是由大神 Steve Francia 開發(fā),他在google領導著 golang 的產(chǎn)品開發(fā),他也是 gohugo.io 的創(chuàng)始人之一,命令行解析庫 cobra 開發(fā)者,這篇文章主要介紹了golang常用庫之配置文件解析庫-viper使用詳解,需要的朋友可以參考下
    2020-10-10
  • Go語言中零拷貝的原理與實現(xiàn)詳解

    Go語言中零拷貝的原理與實現(xiàn)詳解

    零拷貝是相對于用戶態(tài)來講的,即數(shù)據(jù)在用戶態(tài)不發(fā)生任何拷貝,那么零拷貝的原理是什么,又是如何實現(xiàn)的呢,下面小編就來和大家詳細聊聊吧
    2023-08-08
  • golang 項目打包部署環(huán)境變量設置方法

    golang 項目打包部署環(huán)境變量設置方法

    最近將 golang 項目打包部署在不同環(huán)境,下面分享一下我的心得體會,對golang 項目打包部署環(huán)境變量設置方法感興趣的朋友一起看看吧
    2024-07-07
  • 在Golang中使用C語言代碼實例

    在Golang中使用C語言代碼實例

    這篇文章主要介紹了在Golang中使用C語言代碼實例,本文先是給出了一個Hello World例子、Golang 引用 C例子,并總結了一些要注意的地方,需要的朋友可以參考下
    2014-10-10
  • golang使用aes庫實現(xiàn)加解密操作

    golang使用aes庫實現(xiàn)加解密操作

    這篇文章主要介紹了golang使用aes庫實現(xiàn)加解密操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • 一文秒懂Go 編寫命令行工具的代碼

    一文秒懂Go 編寫命令行工具的代碼

    這篇文章主要介紹了一文秒懂Go 編寫命令行工具的代碼,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-01-01
  • golang簡單位運算示例

    golang簡單位運算示例

    這篇文章主要介紹了golang簡單位運算,包括位移運算、取反及位與位或等運算,需要的朋友可以參考下
    2016-07-07

最新評論