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

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

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

前言

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

Timer

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

timer結(jié)構(gòu)體

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

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

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

創(chuàng)建定時(shí)器

func NewTimer(d Duration) *Timer

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

示例:

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

停止定時(shí)器

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

func (t *Timer) Stop() bool

其返回值代表定時(shí)器有沒有超時(shí):

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

示例:

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

重置定時(shí)器

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

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

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

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

實(shí)現(xiàn)原理

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

數(shù)據(jù)結(jié)構(gòu)

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

Timer只有兩個(gè)成員:

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

runtimeTimer

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

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

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

創(chuàng)建Timer

源碼實(shí)現(xiàn):

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

sendTime實(shí)現(xiàn):

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

停止Timer

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

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

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

重置Timer

重置Timer時(shí)會先把timer從系統(tǒng)協(xié)程中刪除,修改新的時(shí)間后重新添加到系統(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 一次性定時(shí)器Timer用法及實(shí)現(xiàn)原理詳解的詳細(xì)內(nèi)容,更多關(guān)于go 一次性定時(shí)器Timer的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Go語言框架Beego項(xiàng)目搭建的方法步驟

    Go語言框架Beego項(xiàng)目搭建的方法步驟

    這篇文章主要介紹了Go語言框架Beego項(xiàng)目搭建的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-05-05
  • Golang中interface{}轉(zhuǎn)為數(shù)組的操作

    Golang中interface{}轉(zhuǎn)為數(shù)組的操作

    這篇文章主要介紹了Golang中interface{}轉(zhuǎn)為數(shù)組的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • golang映射Map的方法步驟

    golang映射Map的方法步驟

    這篇文章主要介紹了golang映射Map的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-09-09
  • golang敏感詞過濾的實(shí)現(xiàn)

    golang敏感詞過濾的實(shí)現(xiàn)

    本文主要介紹了golang敏感詞過濾的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-01-01
  • golang中數(shù)組與切片的區(qū)別詳析

    golang中數(shù)組與切片的區(qū)別詳析

    數(shù)組是固定長度,常量,切片長度是可以改變,所以是一個(gè)可變的數(shù)組,下面這篇文章主要給大家介紹了關(guān)于golang中數(shù)組與切片區(qū)別的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-11-11
  • 用Go語言標(biāo)準(zhǔn)庫實(shí)現(xiàn)Web服務(wù)之創(chuàng)建路由

    用Go語言標(biāo)準(zhǔn)庫實(shí)現(xiàn)Web服務(wù)之創(chuàng)建路由

    在上一節(jié)中創(chuàng)建了項(xiàng)目,這篇文章主要介紹如何用Go語言標(biāo)準(zhǔn)庫創(chuàng)建路由,文中有詳細(xì)的代碼示例,對大家的學(xué)習(xí)或工作有一定的幫助,感興趣的同學(xué)可以參考下
    2023-05-05
  • Go?為什么不支持可重入鎖原理解析

    Go?為什么不支持可重入鎖原理解析

    這篇文章主要為大家介紹了Go?為什么不支持可重入鎖原理解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-08-08
  • 使用golang編寫一個(gè)并發(fā)工作隊(duì)列

    使用golang編寫一個(gè)并發(fā)工作隊(duì)列

    這篇文章主要介紹了使用golang編寫一個(gè)并發(fā)工作隊(duì)列的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • go的strings用法小結(jié)

    go的strings用法小結(jié)

    strings 是 Go 語言標(biāo)準(zhǔn)庫中提供的一個(gè)包,用于處理字符串相關(guān)的操作,本文主要介紹了go的strings用法小結(jié),具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-08-08
  • Go語言實(shí)現(xiàn)字符串切片賦值的方法小結(jié)

    Go語言實(shí)現(xiàn)字符串切片賦值的方法小結(jié)

    這篇文章主要給大家介紹了Go語言實(shí)現(xiàn)字符串切片賦值的兩種方法,分別是在for循環(huán)的range中以及在函數(shù)的參數(shù)傳遞中實(shí)現(xiàn),有需要的朋友們可以根據(jù)自己的需要選擇使用。下面來一起看看吧。
    2016-10-10

最新評論

海城市| 枣阳市| 黄浦区| 疏勒县| 综艺| 无为县| 毕节市| 福贡县| 东乌| 大同县| 正镶白旗| 普兰店市| 福州市| 吉安县| 嘉祥县| 化州市| 潍坊市| 宣化县| 宜川县| 洪洞县| 周至县| 南溪县| 宿松县| 贡山| 阜康市| 富顺县| 呼伦贝尔市| 屯门区| 金塔县| 信宜市| 博客| 红安县| 叶城县| 平阴县| 松原市| 黄陵县| 民权县| 会宁县| 红安县| 鄯善县| 青冈县|