Go語言使用定時器實現任務佇列

2020-07-16 10:05:06
Go語言中提供了兩種定時器 timer 和 ticker,分別是一次性定時器和重復任務定時器。本節咱們主要介紹如何使用Go語言的定時器實現一個任務佇列,非常具有實用價值。

Go語言中定時器

一般用法:
package main

import(
    "fmt"
    "time"
)

func main() {
    input := make(chan interface{})
    //producer - produce the messages
    go func() {
        for i := 0; i < 5; i++ {
            input <- i
        }
        input <- "hello, world"
    }()

    t1 := time.NewTimer(time.Second * 5)
    t2 := time.NewTimer(time.Second * 10)

    for {
        select {
            //consumer - consume the messages
            case msg := <-input:
                fmt.Println(msg)

            case <-t1.C:
                println("5s timer")
                t1.Reset(time.Second * 5)

            case <-t2.C:
                println("10s timer")
                t2.Reset(time.Second * 10)
        }
    }
}
上面程式碼中的這個 C 是啥呢,我們去原始碼看看,以 timer 為例:

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

原來是一個 channel,其實有 GO 基礎的都知道,GO 的運算子當出現的 -> 或者 <- 的時候,必然是有一端是指 channel。按照上面的例子來看,就是阻塞在一個 for 迴圈內,等待到了定時器的 C 從 channel 出來,當獲取到值的時候,進行想要的操作。

設計我們的定時任務佇列

當時的需求是這樣,需要接收到用戶端的請求並產生一個定時任務,會在固定時間執行,可能是一次,也可能是多次,也可能到指定時間自動停止,可能當任務終止的時候,還要能停止掉。

具體的流程如下圖所示: