日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Go Timer使用方法

發(fā)布時(shí)間:2024/4/14 编程问答 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go Timer使用方法 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

為什么80%的碼農(nóng)都做不了架構(gòu)師?>>> ??

簡(jiǎn)介

Timer實(shí)際上是一種單一事件的定時(shí)器,即經(jīng)過(guò)指定的時(shí)間后觸發(fā)一個(gè)事件,這個(gè)事件通過(guò)其本身提供的channel進(jìn)行通知。之所以叫單一事件,是因?yàn)門imer只執(zhí)行一次就結(jié)束,這也是Timer與Ticker的最重要的區(qū)別之一。

通過(guò)timer.NewTimer(d Duration)可以創(chuàng)建一個(gè)timer,參數(shù)即等待的時(shí)間,時(shí)間到來(lái)后立即觸發(fā)一個(gè)事件。

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

type Timer struct { // Timer代表一次定時(shí),時(shí)間到來(lái)后僅發(fā)生一個(gè)事件。C <-chan Timer runtimeTimer }

Timer對(duì)外僅暴露一個(gè)channel,指定的時(shí)間到來(lái)時(shí)就往該channel中寫入系統(tǒng)時(shí)間,也即一個(gè)事件。

本節(jié)我們介紹Timer的幾個(gè)使用場(chǎng)景,同時(shí)再介紹其對(duì)外呈現(xiàn)的方法。

使用場(chǎng)景

設(shè)定超時(shí)時(shí)間

有時(shí)我們希望從一個(gè)管道中讀取數(shù)據(jù),在管道中沒(méi)有數(shù)據(jù)時(shí),我們不想讓程序永遠(yuǎn)阻塞在管道中,而是設(shè)定一個(gè)超時(shí)時(shí)間,在此時(shí)間段中如果管道中還是沒(méi)有數(shù)據(jù)到來(lái),則判定為超時(shí)。

Go源碼包中有大量類似的用法,比如從一個(gè)連接中等待數(shù)據(jù),其簡(jiǎn)單的用法如下代碼所示:

func WaitChannel(conn <-chan string) bool {timer := time.NewTimer(1 * time.Second)select {case <- conn:timer.Stop()return truecase <- timer.C: // 超時(shí)println("WaitChannel timeout!")return false} }

WaitChannel作用就是檢測(cè)指定的管道中是否有數(shù)據(jù)到來(lái),通過(guò)select語(yǔ)句輪詢conn和timer.C兩個(gè)管道,timer會(huì)在1s后向timer.C寫入數(shù)據(jù),如果1s內(nèi)conn還沒(méi)有數(shù)據(jù),則會(huì)判斷為超時(shí)。

延遲執(zhí)行某個(gè)方法

有時(shí)我們希望某個(gè)方法在今后的某個(gè)時(shí)刻執(zhí)行,如下代碼所示:

func DelayFunction() {timer := time.NewTimer(5 * time.Second)select {case <- timer.C:log.Println("Delayed 5s, start to do something.")} }

DelayFunction()會(huì)一直等待timer的事件到來(lái)才會(huì)執(zhí)行后面的方法(打印)。

Timer對(duì)外接口

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

使用方法func NewTimer(d Duration) *Timer指定一個(gè)時(shí)間即可創(chuàng)建一個(gè)Timer,Timer一經(jīng)創(chuàng)建便開(kāi)始計(jì)時(shí),不需要額外的啟動(dòng)命令。

實(shí)際上,創(chuàng)建Timer意味著把一個(gè)計(jì)時(shí)任務(wù)交給系統(tǒng)守護(hù)協(xié)程,該協(xié)程管理著所有的Timer,當(dāng)Timer的時(shí)間到達(dá)后向Timer的管道中發(fā)送當(dāng)前的時(shí)間作為事件。詳細(xì)的實(shí)現(xiàn)原理我們后面會(huì)單獨(dú)介紹。

停止定時(shí)器

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

func (t *Timer) Stop() bool

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

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

實(shí)際上,停止計(jì)時(shí)器意味著通知系統(tǒng)守護(hù)協(xié)程移除該定時(shí)器。詳細(xì)的實(shí)現(xiàn)原理我們后面單獨(dú)介紹。

重置定時(shí)器

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

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

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

需要注意的是,重置定時(shí)器雖然可以用于修改還未超時(shí)的定時(shí)器,但正確的使用方式還是針對(duì)已過(guò)期的定時(shí)器或已被停止的定時(shí)器,同時(shí)其返回值也不可靠,返回值存在的價(jià)值僅僅是與前面版本兼容。

實(shí)際上,重置定時(shí)器意味著通知系統(tǒng)守護(hù)協(xié)程移除該定時(shí)器,重新設(shè)定時(shí)間后,再把定時(shí)器交給守護(hù)協(xié)程。詳細(xì)的實(shí)現(xiàn)原理我們后面單獨(dú)介紹。

簡(jiǎn)單接口

前面介紹了Timer的標(biāo)準(zhǔn)接口,time包同時(shí)還提供了一些簡(jiǎn)單的方法,在特定的場(chǎng)景下可以簡(jiǎn)化代碼。

After()

有時(shí)我們就是想等指定的時(shí)間,沒(méi)有需求提前停止定時(shí)器,也沒(méi)有需求復(fù)用該定時(shí)器,那么可以使用匿名的定時(shí)器。

func After(d Duration) <-chan Time方法創(chuàng)建一個(gè)定時(shí)器,并返回定時(shí)器的管道,如下代碼所示:

func AfterDemo() {log.Println(time.Now())<- time.After(1 * time.Second)log.Println(time.Now()) }

AfterDemo()兩條打印時(shí)間間隔為1s,實(shí)際還是一個(gè)定時(shí)器,但代碼變得更簡(jiǎn)潔。

AfterFunc()

前面我們例子中講到延遲一個(gè)方法的調(diào)用,實(shí)際上通過(guò)AfterFunc可以更簡(jiǎn)潔。AfterFunc的原型為:

func AfterFunc(d Duration, f func()) *Timer

該方法在指定時(shí)間到來(lái)后會(huì)執(zhí)行函數(shù)f。例如:

func AfterFuncDemo() {log.Println("AfterFuncDemo start: ", time.Now())time.AfterFunc(1 * time.Second, func() {log.Println("AfterFuncDemo end: ", time.Now())})time.Sleep(2 * time.Second) // 等待協(xié)程退出 }

AfterFuncDemo()中先打印一個(gè)時(shí)間,然后使用AfterFunc啟動(dòng)一個(gè)定器,并指定定時(shí)器結(jié)束時(shí)執(zhí)行一個(gè)方法打印結(jié)束時(shí)間。

與上面的例子所不同的是,time.AfterFunc()是異步執(zhí)行的,所以需要在函數(shù)最后sleep等待指定的協(xié)程退出,否則可能函數(shù)結(jié)束時(shí)協(xié)程還未執(zhí)行。

總結(jié)

本節(jié)簡(jiǎn)單介紹了Timer的常見(jiàn)使用場(chǎng)景和接口,后面的章節(jié)再介紹Ticker、以及二者的實(shí)際細(xì)節(jié)。

Timer內(nèi)容總結(jié)如下:

  • time.NewTimer(d)創(chuàng)建一個(gè)Timer;
  • timer.Stop()停掉當(dāng)前Timer;
  • timer.Reset(d)重置當(dāng)前Timer;

贈(zèng)人玫瑰手留余香,如果覺(jué)得不錯(cuò)請(qǐng)給個(gè)贊~

本篇文章已歸檔到GitHub項(xiàng)目,求星~ 點(diǎn)我即達(dá)

轉(zhuǎn)載于:https://my.oschina.net/renhc/blog/3026957

總結(jié)

以上是生活随笔為你收集整理的Go Timer使用方法的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。