golang time包下定時器的實現方法

2022-09-29 06:06:07 字數 3037 閱讀 2186

golang time包

時間戳

當前時間戳

fmt.println(time.now().unix())

# 1389058332

str格式化時間

當前格式化時間

fmt.println(time.now().format("2006-01-02 15:04:05")) // 這是個奇葩,必須是這個時間點, 據說是go誕生之日, 記憶方法:6-1-2-3-4-5

# 2014-01-07 09:42:20

時間戳轉str格式化時間

str_time := time.unix(1389058332, 0).format("2006-01-02 15:04:05")

fmt.println(str_time)

# 2014-01-07 09:32:12

str格式化時間轉時間戳

這個比較麻煩

the_time := time.date(2014, 1, 7, 5, 50, 4, 0, time.local)

unix_time := the_time.unix()

fmt.println(unix_time)

# 389045004

還有一種方法,使用time.parse

the_time, err := time.parse("2006-01-02 15:04:05", "2014-01-08 09:04:41")

if err == nil

# 1389171881

以上簡單介紹了golang中time包的相關內容,下面開始本文的正文。

引言這篇文章簡單的介紹下golang time 包下定時器的實現,說道定時器,在我們開發過程中很常用,由於使用的場景不同,所以對定時器實際的實現也就不同,go的定時器並沒有使用sigalarm訊號實現,而是採取最小堆的方式實現(原始碼包中使用陣列實現的四叉樹),使用這種方式定時精度很高,但是有的時候可能我們不需要這麼高精度的實現,為了更高效的利用資源,有的時候也會實現乙個精度比較低的演算法。

跟golang定時器相關的入口主要有以下幾種方法:

這裡我們以其中newticker為入口,newticker的原始碼如下:

func程式設計客棧 newticker(d duration) *ticker

c := make(chan time, 1)

t := &ticker,

} // 將新的定時任務新增到時間堆中

// 編譯器會將這個函式翻譯為runtime.starttimer(t *runtime.timer)

// time.runtimetimer翻譯為runtime.timer

starttimer(&t.r)

return t

這裡有個比較重要的是starttimer(&t.r)它的實現被翻譯在runtime包內

func starttimer(t *timer)

addtimer(t)

}func addtimer(t *timer)

上面的**為了看著方便,我將他們都放在一起

下面**都寫出部分注釋

// 使用鎖將計時器新增到堆中

// 如果是第一次執行此方法則啟動timerproc

func addtimerlocked(t *timer)

// t.i i是定時任務陣列中的索引

// 將新的定時任務追加到定時任務陣列隊尾

t.i = len(timers.t)

timers.t = append(timers.t, t)

// 使用陣列實現的四叉樹最小堆根據when(到期時間)進行排序

siftuptimer(t.i)

// 如果t.i 索引為0

if t.i == 0

if timers.rescheduling

} if !timers.created

}// timerproc執行時間驅動的事件。

// 它sleep到計時器堆中的下乙個。

// 如果addtimer插入乙個新的事件,它會提前喚醒timerproc。

func timerproc(

t := timers.t[0]

delta = t.when - now

if delta > 0

if t.period > 0 else

timers.t[last] = nil

timers.t = timers.t[:last]

if last > 0

t.i = -1 // 標記移除

} f := t.f

arg := t.arg

seq := t.seq

unlock(&timers.lock)

if raceenabled

f(arg, seq)

lock(&timers.lock)

} if delta < 0 || faketime > 0

// at least one timer pending. sleep until then.

timers.sleeping = true

timers.sleepuntil = now + delta

// 重置

noteclear(&timers.waitnote)

unlock(&timers.lock)

// 使goroutine進入睡眠狀態,直到notewakeup被呼叫,

// 通過notewakeupwww.cppcns.com 喚醒

notetsleepg(&timers.waitnote, delta)

}}golang使用最小堆(最小堆是滿足除了根節點以外的每個節點都不小於其父節點的堆)實現的定時器。golang *timer結構如下:

golang儲存定時任務結構

addtimer在堆中插入乙個值,然後保持最小堆的特性,其實這個結構本質就是最小優先佇列的乙個應用,然後將時間轉換乙個絕對時間處理,通過睡眠和喚醒找出定時任務,這裡閱讀起**碼很容易,所以只將**和部分注釋寫出。

總結本文標題: golang time包下定時器的實現方法

本文位址:

linux 下定時器 crontab

1.直接用crontab命令編輯 cron服務提供crontab命令來設定cron服務的,以下是這個命令的一些引數與說明 crontab u 設定某個使用者的cron服務,一般root使用者在執行這個命令的時候需要此引數 crontab l 列出某個使用者cron服務的詳細內容 crontab r ...

linux下定時器實現

linux定時器 是指在每隔一段時間後就會進行一次相關操作,具有計時性的。核心操作是如下方法 int setitimer int which,const struct itimerval restrict value,struct itimerval restrict ovalue 函式返回的是va...

linux下定時器的使用

linux下定時器的使用主要用到兩個函式 setitimer 和getitimer linux系統給每個程序提供了3個定時器,每個定時器在各自不同的域裡面計數,當任何乙個timer計數結束了,系統就發乙個訊號 signal 給該程序,同時計數器重置。以下是支援的三種計數器形式 1 itimer re...