溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Go 定時(shí)器和斷續(xù)器

發(fā)布時(shí)間:2020-07-19 01:54:53 來(lái)源:網(wǎng)絡(luò) 閱讀:6276 作者:quenlang 欄目:開發(fā)技術(shù)

1、定時(shí)器

Go語(yǔ)言中定時(shí)器可以實(shí)現(xiàn)在指定時(shí)間點(diǎn)執(zhí)行特定的事件,定時(shí)器的實(shí)質(zhì)是單向通道,time.Timer結(jié)構(gòu)體類型中有一個(gè)time.Time類型的單向chan,具體聲明如下:

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

只能通過(guò)兩種方式來(lái)進(jìn)行初始化:time.NewTimer()和time.AfterFunc(),看如下代碼:

package main

import (
    "fmt"
    "time"
)

func main() {
    // NewTimer方法接受一個(gè)時(shí)間段d表示自此刻起經(jīng)歷d時(shí)間段后,定時(shí)器到期;返回值為*Timer類型,到期后將到期時(shí)的時(shí)間寫入*Timer的C(chan time.Time)字段中
    t := time.NewTimer(2 * time.Second)
    now := time.Now()
    fmt.Printf("Now time: %v\n", now)
    // 改行代碼會(huì)阻塞當(dāng)前的goroutine,直到t.C中傳入一個(gè)元素
    expire := <-t.C
    fmt.Printf("Expire time: %v\n", expire)
}
package main

import (
    "fmt"
    "time"
)

func main() {
    var t *time.Timer
    f := func() {
        fmt.Printf("Expriation time: %v\n", time.Now())
        fmt.Printf("C`s length: %v\n", len(t.C))
    }
    // 在定時(shí)器過(guò)期時(shí)執(zhí)行一個(gè)自定義的無(wú)接受參數(shù)和輸出參數(shù)的函數(shù)
    t = time.AfterFunc(1*time.Second, f)
    // 為了結(jié)果輸出完全
    time.Sleep(2 * time.Second)
}

如果不使用時(shí)器的Stop()和Reset()方法,可以直接用定時(shí)器的快捷方法,如下:

package main

import (
    "fmt"
    "time"
)

func main() {
    fmt.Printf("Now time:%v\n", time.Now())
    c := <-time.After(5 * time.Second)
    fmt.Printf("TimeOut. Now :%v\n", c)
}

如果在定時(shí)器到期之前,使用Stop(),那么就不會(huì)再有元素寫入通道內(nèi),那么等待接受該通道元素所在的goroutine將被阻塞,恢復(fù)被停止的定時(shí)器的唯一途徑是使用Reset()方法重置;定時(shí)器可以復(fù)用,尤其是在for循環(huán)中復(fù)用可以減少程序的資源占用,這時(shí)需要Reset()方法來(lái)重置定時(shí)器。


2、斷續(xù)器

Go提供了循環(huán)多次的執(zhí)行某一任務(wù)的工具,續(xù)斷器,實(shí)質(zhì)是單向通道,time.結(jié)構(gòu)體類型中有一個(gè)time.Time類型的單向chan,具體聲明如下:

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

續(xù)斷器使用NewTicker()來(lái)初始化,代碼如下:

package main

import (
    "fmt"
    "time"
)

func main() {
    ticks := time.NewTicker(30 * time.Second)
    tick := ticks.C
    go func() {
        // for...range...相當(dāng)于從通道取一個(gè)元素
        for _ = range tick {
            fmt.Printf("%vExecute the task.\n", time.Now())
            // 再次執(zhí)行接受操作時(shí),由于通道內(nèi)暫時(shí)沒有值,就會(huì)被阻塞,直到下次觸發(fā)到期
            _, ok := <-tick
            if !ok {
                break
            }
        }
    }()
    fmt.Printf("Now: %v.\n", time.Now())
    time.Sleep(5 * time.Minute)
    fmt.Println("Done.")
}

如果不使用續(xù)斷器的Stop()方法,可以直接使用續(xù)斷器的快捷方法,如下

tick := <-time.Tick(5 * time.Second)
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI