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

Golang當(dāng)中的定時(shí)器實(shí)例詳解

 更新時(shí)間:2023年07月10日 08:35:50   作者:一個(gè)山里的少年  
這篇文章主要給大家介紹了關(guān)于Golang當(dāng)中定時(shí)器的相關(guān)資料,定時(shí)器的實(shí)現(xiàn)大家應(yīng)該都遇到過(guò),最近在學(xué)習(xí)golang,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

在平時(shí)寫(xiě)代碼的時(shí)候,我們經(jīng)常會(huì)遇到在將來(lái)某個(gè)時(shí)間點(diǎn)或者間隔一段時(shí)間重復(fù)執(zhí)行函數(shù)。這個(gè)時(shí)候我們就可以考慮使用定時(shí)器。本片文章主要介紹一下golang當(dāng)中的幾個(gè)常用的定時(shí)器。time.Timer,time.Ticker,time.After以及time.AfterFunc和time.Ticker的基本使用

定時(shí)器的基本使用

golang當(dāng)中的定時(shí)器有這個(gè)一次性的定時(shí)器(Timer)和周期性的定時(shí)器(Ticker).在平時(shí)的編程當(dāng)中經(jīng)常會(huì)使用timer當(dāng)中的ticker,AfterFunc定時(shí)器,而NewTicker是每隔多長(zhǎng)時(shí)間觸發(fā),NewTimer是等待多長(zhǎng)時(shí)間觸發(fā)一次請(qǐng)注意是只觸發(fā)一次。請(qǐng)注意一下兩者的區(qū)別。
下面我們來(lái)首先來(lái)使用一下這兩個(gè)定時(shí)器首先是這個(gè)Timer定時(shí)器

package main

import (
	"fmt"
	"time"
)
func main() {
	myTimer := time.NewTimer(time.Second * 3) //初始化定時(shí)器
	var i = 0
	for {
		select {
		case <-myTimer.C:
			i++
			fmt.Printf("the counter is%d", i)
			myTimer.Reset(time.Second * 3) //注意需要重新設(shè)置
		}
	}
	myTimer.Stop() //不在使用需要將其停止
}

注意這個(gè)timer定時(shí)器超時(shí)之后需要重新進(jìn)行設(shè)置,才能重新觸發(fā)。如果上面的代碼我們沒(méi)有Reset,那么就會(huì)導(dǎo)致死鎖。其實(shí)我們也可以看看這個(gè)Timer是怎么是實(shí)現(xiàn)的

func NewTimer(d Duration) *Timer {
    c := make(chan Time, 1)
    t := &Timer{
        C: c,  // 信道
        r: runtimeTimer{
            when: when(d),  // 觸發(fā)時(shí)間
            f:    sendTime, // 時(shí)間到了之后的調(diào)用函數(shù)
            arg:  c,        // 調(diào)用sendTime時(shí)的入?yún)?
        },
    }
    startTimer(&t.r)  // 把定時(shí)器的r字段放入由定時(shí)器維護(hù)協(xié)程維護(hù)的堆中
    return t
} 

從上面的構(gòu)造函數(shù)中可以大概看出定時(shí)器的工作流程,這里面最重要的是runtimeTimer。構(gòu)造定時(shí)器的時(shí)候會(huì)把runtimeTimer放入由定時(shí)器維護(hù)協(xié)程維護(hù)的堆中,當(dāng)時(shí)間到了之后,維護(hù)協(xié)程把r從堆中移除,并調(diào)用r的sendTime函數(shù),sendTime的入?yún)⑹嵌〞r(shí)器的信道C??梢酝茢?,sendTime中執(zhí)行的邏輯應(yīng)該是向信道C中推送時(shí)間,通知上游系統(tǒng)時(shí)間到了,而事實(shí)正是如此:

func sendTime(c interface{}, seq uintptr) {
    // Non-blocking send of time on c.
    // Used in NewTimer, it cannot block anyway (buffer).
    // Used in NewTicker, dropping sends on the floor is
    // the desired behavior when the reader gets behind,
    // because the sends are periodic.
    select {
    case c.(chan Time) <- Now():  //時(shí)間到了之后把當(dāng)前時(shí)間放入信道中
    default:
    }
} 

其實(shí)這個(gè)time.After就是對(duì)這個(gè)time.Timer的一個(gè)封裝,所以如果我們上面使用這個(gè)time.After那么會(huì)頻繁的創(chuàng)建time.Timer對(duì)象
下面我們?cè)趤?lái)看一下這個(gè)time.AterFunc()定時(shí)器。

Golang當(dāng)中的AfterFunc函數(shù)用于等待經(jīng)過(guò)時(shí)間,此后在其自己的協(xié)程當(dāng)中調(diào)用定義的函數(shù)f.函數(shù)在時(shí)間包下定義。下面我們一起看看如何使用這個(gè)

import (
	"fmt"
	"time"
)

func main() {
	f := func() {
		fmt.Println("the func is call after 3 second")
	}
	myTime := time.AfterFunc(time.Second*3, f)

	defer myTime.Stop() //定時(shí)器不用了需要關(guān)閉
	time.Sleep(time.Second * 4)
}

下面我們?cè)诳纯催@個(gè)time.NewTicker定時(shí)器的使用

package main

import (
	"fmt"
	"time"
)

func main() {
	mytick := time.NewTicker(time.Second * 2)
	defer mytick.Stop() //定時(shí)器不用了需要關(guān)閉
	done := make(chan struct{})
	go func() {
		for {
			time.Sleep(time.Second * 10)
			done <- struct{}{}
		}
	}()
	for {
		select {
		case <-done:
			fmt.Println("done!!!!")
			return
		case t := <-mytick.C:
			fmt.Printf("the curtime is %v\n", t)
		}
	}

}

下面我們來(lái)看一下這個(gè)陷阱,這個(gè)需要注意

package main
import (
	"fmt"
	"time"
)
func main() {
	var count int
	for {
		select {
		case <-time.Tick(time.Second * 1):
			fmt.Println("case1")
			count++
			fmt.Println("count--->", count)
		case <-time.Tick(time.Second * 2):
			fmt.Println("case2")
			count++
			fmt.Println("count--->", count)
		}
	}
}

這個(gè)代碼是有陷阱的,下面我們來(lái)看看這個(gè)運(yùn)行結(jié)果是什么?

可見(jiàn) case2 永遠(yuǎn)沒(méi)有被執(zhí)行到,問(wèn)題就出在代碼邏輯上,首先看time.Tick方法。我們可以看一下這個(gè)方法就知道

func Tick(d Duration) <-chan Time {
	if d <= 0 {
		return nil
	}
	return NewTicker(d).C
}

它每次都會(huì)創(chuàng)建一個(gè)新的定時(shí)器,隨著 for 循環(huán)進(jìn)行, select 始終監(jiān)聽(tīng)兩個(gè)新創(chuàng)建的定時(shí)器,老的定時(shí)器被拋棄掉了,也就不會(huì)去讀取老定時(shí)器中的通道。

select 可以同時(shí)監(jiān)聽(tīng)多個(gè)通道,誰(shuí)先到達(dá)就先讀取誰(shuí),如果同時(shí)有多個(gè)通道有消息到達(dá),那么會(huì)隨機(jī)讀取一個(gè)通道,其他的通道由于沒(méi)有被讀取,所以數(shù)據(jù)不會(huì)丟失,需要循環(huán)調(diào)用 select 來(lái)讀取剩下的通道。

總結(jié):

  • tick創(chuàng)建完成之后,不是馬上有一個(gè)tick.第一個(gè)tick在你設(shè)置的多少秒之后才會(huì)進(jìn)行創(chuàng)建
  • golang當(dāng)中的定時(shí)器實(shí)質(zhì)上是這個(gè)單項(xiàng)的管道
  • time.NewTicker會(huì)定時(shí)觸發(fā)任務(wù),當(dāng)下一次執(zhí)行到來(lái)而當(dāng)前任務(wù)畫(huà)面執(zhí)行完,會(huì)等待當(dāng)前任務(wù)執(zhí)行完畢在進(jìn)行下一次任務(wù)。
  • Ticker和Timer的不同之處是,Ticker時(shí)間到達(dá)之后不需要人為的調(diào)用Reset方法來(lái)重新設(shè)置時(shí)間

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

相關(guān)文章

  • Go語(yǔ)言中的通道chan使用指南

    Go語(yǔ)言中的通道chan使用指南

    Go語(yǔ)言的通道chan是實(shí)現(xiàn)并發(fā)編程的關(guān)鍵工具,主要用于goroutine之間的數(shù)據(jù)傳輸,本文主要介紹了通道的基本操作如創(chuàng)建、發(fā)送、接收和關(guān)閉數(shù)據(jù),以及使用select語(yǔ)句進(jìn)行多路復(fù)用和超時(shí)控制,感興趣的可以了解一下
    2024-10-10
  • golang并發(fā)執(zhí)行的幾種方式小結(jié)

    golang并發(fā)執(zhí)行的幾種方式小結(jié)

    本文主要介紹了golang并發(fā)執(zhí)行的幾種方式小結(jié),主要包括了Channel,WaitGroup ,Context,使用這三種機(jī)制中的一種或者多種可以達(dá)到并發(fā)控制很好的效果,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-08-08
  • golang連接kafka的示例代碼

    golang連接kafka的示例代碼

    本文主要介紹了golang連接kafka的示例代碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • Go實(shí)現(xiàn)生產(chǎn)隨機(jī)密碼的示例代碼

    Go實(shí)現(xiàn)生產(chǎn)隨機(jī)密碼的示例代碼

    這篇文章主要為大家詳細(xì)介紹了如何利用Go實(shí)現(xiàn)生產(chǎn)隨機(jī)密碼的,文中的示例代碼簡(jiǎn)潔易懂,具有一定的借鑒價(jià)值,有需要的小伙伴可以參考一下
    2023-09-09
  • go語(yǔ)言按顯示長(zhǎng)度截取字符串的方法

    go語(yǔ)言按顯示長(zhǎng)度截取字符串的方法

    這篇文章主要介紹了go語(yǔ)言按顯示長(zhǎng)度截取字符串的方法,涉及Go語(yǔ)言操作字符串的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • 使用Golang操作TMDb?API的使用小結(jié)

    使用Golang操作TMDb?API的使用小結(jié)

    本文主要介紹了使用Golang操作TMDb?API的使用小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2026-05-05
  • Go語(yǔ)言超時(shí)退出的三種實(shí)現(xiàn)方式總結(jié)

    Go語(yǔ)言超時(shí)退出的三種實(shí)現(xiàn)方式總結(jié)

    這篇文章主要為大家詳細(xì)介紹了Go語(yǔ)言中超時(shí)退出的三種實(shí)現(xiàn)方式,文中的示例代碼簡(jiǎn)潔易懂,對(duì)我們深入了解Go語(yǔ)言有一定的幫助,需要的可以了解一下
    2023-06-06
  • Go設(shè)計(jì)模式之備忘錄模式圖文詳解

    Go設(shè)計(jì)模式之備忘錄模式圖文詳解

    備忘錄模式是一種行為設(shè)計(jì)模式, 允許在不暴露對(duì)象實(shí)現(xiàn)細(xì)節(jié)的情況下保存和恢復(fù)對(duì)象之前的狀態(tài),本文主要通過(guò)一些圖片來(lái)給大家介紹一下Go的備忘錄模式,需要的朋友可以參考下
    2023-08-08
  • Golang打印復(fù)雜結(jié)構(gòu)體兩種方法詳解

    Golang打印復(fù)雜結(jié)構(gòu)體兩種方法詳解

    在?Golang?語(yǔ)言開(kāi)發(fā)中,我們經(jīng)常會(huì)使用結(jié)構(gòu)體類(lèi)型,如果我們使用的結(jié)構(gòu)體類(lèi)型的變量包含指針類(lèi)型的字段,我們?cè)谟涗浫罩镜臅r(shí)候,指針類(lèi)型的字段的值是指針地址,將會(huì)給我們?debug?代碼造成不便
    2022-10-10
  • Go的ORM框架的使用

    Go的ORM框架的使用

    GORM是一個(gè)功能豐富的Go語(yǔ)言O(shè)RM框架,提供全功能的數(shù)據(jù)庫(kù)操作支持,本文就來(lái)介紹一下GORM框架的使用,感興趣的可以了解一下
    2026-01-01

最新評(píng)論

大田县| 梧州市| 冷水江市| 襄樊市| 开封县| 靖安县| 外汇| 东乌珠穆沁旗| 三台县| 闽清县| 沾益县| 石嘴山市| 莆田市| 新津县| SHOW| 军事| 曲麻莱县| 沂源县| 瓮安县| 冷水江市| 衡阳县| 上蔡县| 东阳市| 新竹市| 藁城市| 白河县| 钦州市| 常熟市| 伊通| 盐边县| 杨浦区| 鸡泽县| 崇文区| 陆良县| 石城县| 哈密市| 商河县| 舒兰市| 米脂县| 年辖:市辖区| 八宿县|