bl双性强迫侵犯h_国产在线观看人成激情视频_蜜芽188_被诱拐的少孩全彩啪啪漫画

go語(yǔ)言計(jì)時(shí)器 go語(yǔ)言定時(shí)任務(wù)

計(jì)時(shí)器中四叉堆的變遷

在我們編碼過(guò)程中,經(jīng)常會(huì)用到與時(shí)間相關(guān)的需求。而關(guān)于時(shí)間轉(zhuǎn)換之類的比較簡(jiǎn)單,那么計(jì)時(shí)器經(jīng)過(guò)了以下幾個(gè)版本的迭代:

10多年專業(yè)網(wǎng)站制作公司歷程,堅(jiān)持以創(chuàng)新為先導(dǎo)的網(wǎng)站服務(wù),服務(wù)超過(guò)成百上千家企業(yè)及個(gè)人,涉及網(wǎng)站設(shè)計(jì)、重慶App定制開(kāi)發(fā)、微信開(kāi)發(fā)、平面設(shè)計(jì)、互聯(lián)網(wǎng)整合營(yíng)銷等多個(gè)領(lǐng)域。在不同行業(yè)和領(lǐng)域給人們的工作和生活帶來(lái)美好變化。

Go1.10之前的計(jì)時(shí)器的結(jié)構(gòu)體如下所示

注意這個(gè)結(jié)構(gòu)體是用var變量定義的,它會(huì)存儲(chǔ)所有的計(jì)時(shí)器。t就是最小四叉堆,運(yùn)行時(shí)創(chuàng)建的所有計(jì)時(shí)器都會(huì)加入到四叉堆中。

由一個(gè)獨(dú)立的timerproc通過(guò)最小四叉堆和futexsleep來(lái)管理定時(shí)任務(wù)。

但是全局四叉堆共用一把鎖對(duì)性能的影響非常大,所以Go1.10之后將全局四叉堆分割成了64個(gè)更小的四叉堆。

在理想情況下,四叉堆的數(shù)量應(yīng)該等于處理器的數(shù)量GOMAXPROCS,但是需要?jiǎng)討B(tài)獲取處理的數(shù)量,所以經(jīng)過(guò)權(quán)衡初始化64個(gè)四叉堆,如果當(dāng)前機(jī)器的處理器P的個(gè)數(shù)超過(guò)了64個(gè),多個(gè)處理器的計(jì)時(shí)器可能會(huì)存儲(chǔ)在同一個(gè)桶中。

將全局計(jì)時(shí)器分片,雖然能夠降低鎖的粒度,但是timerproc造成處理器和線程之間頻繁的上下文切換卻成為了影響計(jì)時(shí)器的瓶頸。

在Go1.14版本之后,計(jì)時(shí)器桶timersBucket已經(jīng)被移除了,所有的計(jì)時(shí)器都以最小四叉堆的形式存儲(chǔ)在P中。

在p結(jié)構(gòu)體中有以下字段與計(jì)時(shí)器關(guān)聯(lián):

而計(jì)時(shí)器的結(jié)構(gòu)體為:

這個(gè)僅僅只是runtime/time.go運(yùn)行時(shí)內(nèi)部處理的結(jié)構(gòu),而真正對(duì)外暴露的計(jì)時(shí)器的結(jié)構(gòu)體是:

通過(guò)channel來(lái)通知計(jì)時(shí)器時(shí)間

在runtime/time.go文件下,我們可以看到下面幾個(gè)方法:

當(dāng)通過(guò)time.NewTimer方法增加新的計(jì)時(shí)器時(shí),會(huì)執(zhí)行startTimer來(lái)增加計(jì)時(shí)器

狀態(tài)從timerNoStatus-timerWaiting,其他狀態(tài)會(huì)拋出異常

1、調(diào)用cleantimers清除處理器P中的計(jì)時(shí)器,可以加快創(chuàng)建和刪除計(jì)時(shí)器的程序速度

2、調(diào)用doaddtimer將當(dāng)前計(jì)時(shí)器加入到處理器P的四叉堆timers中

3、調(diào)用wakeNetPoller喚醒網(wǎng)絡(luò)輪詢器中休眠的線程,檢查timer被喚醒的時(shí)間when是否在當(dāng)前輪詢預(yù)期的運(yùn)行時(shí)間內(nèi),如果是就喚醒。

當(dāng)通過(guò)調(diào)用timer.Stop停止計(jì)時(shí)器時(shí),會(huì)執(zhí)行stopTimer來(lái)停止計(jì)時(shí)器

deltimer會(huì)標(biāo)記需要?jiǎng)h除的計(jì)時(shí)器。在刪除計(jì)時(shí)器的過(guò)程中,可能會(huì)遇到其他處理器P的計(jì)時(shí)器,所以我們僅僅只是將狀態(tài)標(biāo)記為刪除,處理器P執(zhí)行刪除操作。

當(dāng)通過(guò)調(diào)用timer.Reset重置定時(shí)器時(shí),會(huì)執(zhí)行resetTimer來(lái)重置定時(shí)器

modtimer會(huì)修改已經(jīng)存在的計(jì)時(shí)器,會(huì)根據(jù)以下規(guī)則處理計(jì)時(shí)器狀態(tài)

狀態(tài)為timerNoStatus, timerRemoved會(huì)被標(biāo)記為已刪除wasRemoved,就會(huì)調(diào)用doaddtimer新創(chuàng)建一個(gè)計(jì)時(shí)器。

而在正常情況下會(huì)根據(jù)修改后的時(shí)間進(jìn)行不同的處理:

會(huì)根據(jù)狀態(tài)清除處理器P的最小四叉堆隊(duì)頭的計(jì)時(shí)器

在GPM調(diào)度的時(shí)候檢查計(jì)時(shí)器

與cleantimers不同的是,adjusttimers會(huì)遍歷處理器P轉(zhuǎn)給你所有的計(jì)時(shí)器

會(huì)檢查四叉堆堆頂?shù)挠?jì)時(shí)器,根據(jù)狀態(tài)處理計(jì)時(shí)器

1、狀態(tài)是timerDeleted,狀態(tài)變?yōu)閠imerDeleted,然后刪除計(jì)時(shí)器,再變更狀態(tài)為timerRemoved

2、狀態(tài)是timerModifiedXXX

3、狀態(tài)是timerWaiting,如果計(jì)時(shí)器沒(méi)有到達(dá)觸發(fā)時(shí)間,直接返回,否則狀態(tài)變?yōu)閠imerRunning,調(diào)用runOneTimer運(yùn)行堆頂?shù)挠?jì)時(shí)器

根據(jù)period字段是否大于0判斷,如果大于0

如果小于等于0:

更新完?duì)顟B(tài)后,回調(diào)函數(shù)f(arg, seq)執(zhí)行方法。

在adjesttimers中提到過(guò)

checkTimers是調(diào)度器用來(lái)運(yùn)行處理器P中定時(shí)器的函數(shù),會(huì)在以下幾種情況被觸發(fā):

1、先通過(guò)處理器P字段中updateTimer0When判斷是否有需要執(zhí)行的計(jì)時(shí)器,如果沒(méi)有直接返回

2、如果下一個(gè)計(jì)時(shí)器沒(méi)有到期但是需要?jiǎng)h除的計(jì)時(shí)器較少時(shí)會(huì)直接返回

3、加鎖

4、需要處理的timer,根據(jù)時(shí)間將timers切片中的timer重新排序,調(diào)用adjusttimers

5、會(huì)通過(guò)runtimer依次查找運(yùn)行計(jì)時(shí)器

6、處理器中已刪除的timer大于p上的timer數(shù)量的1/4,對(duì)標(biāo)記為timerDeleted的timer進(jìn)行清理

7、解鎖

go1.10最多可以創(chuàng)建GOMAXPROCS數(shù)量的timerproc協(xié)程,當(dāng)然不超過(guò)64。但我們要知道timerproc自身就是協(xié)程,也需要runtime pmg的調(diào)度。到go 1.14把檢查到期定時(shí)任務(wù)的工作交給了網(wǎng)絡(luò)輪詢器,不需要額外的調(diào)度,每次runtime.schedule和findrunable時(shí)直接運(yùn)行到期的定時(shí)任務(wù)。

go 語(yǔ)言中的 rune

rune是Go語(yǔ)言中一種特殊的數(shù)據(jù)類型,它是int32的別名,幾乎在所有方面等同于int32,用于區(qū)分字符值和整數(shù)值,官方解釋如下:

下面我們通過(guò)一個(gè)例子來(lái)看一下:

我們猜測(cè)一下結(jié)果,hello5 個(gè)字符+1 個(gè)空格+3 個(gè)漢子,算起來(lái)應(yīng)該是 9 個(gè),長(zhǎng)度為 9 才對(duì),但是我們執(zhí)行一下,

結(jié)果打印是 15,這是為什么呢?

所以計(jì)算出的長(zhǎng)度就等于 5+1+3*3=15

如果我們需要計(jì)算出字符串的長(zhǎng)度,而不是底層字節(jié)的個(gè)數(shù),那么可以使用下面的方法:

運(yùn)行結(jié)果如下:

在 rune 定義上方還有一個(gè),byte = uint8

golang 獲取時(shí)間精確能到納秒嗎

這樣。不過(guò)只是個(gè)精確到納秒的計(jì)時(shí)器,不是精確到納秒的當(dāng)前時(shí)間。windows好像只能拿到ms精度的當(dāng)前時(shí)間吧,不是很清楚。

package main

import (

"syscall"

"time"

"unsafe"

)

func NewStopWatch() func() time.Duration {

var QPCTimer func() func() time.Duration

QPCTimer = func() func() time.Duration {

lib, _ := syscall.LoadLibrary("kernel32.dll")

qpc, _ := syscall.GetProcAddress(lib, "QueryPerformanceCounter")

qpf, _ := syscall.GetProcAddress(lib, "QueryPerformanceFrequency")

if qpc == 0 || qpf == 0 {

return nil

}

var freq, start uint64

syscall.Syscall(qpf, 1, uintptr(unsafe.Pointer(freq)), 0, 0)

syscall.Syscall(qpc, 1, uintptr(unsafe.Pointer(start)), 0, 0)

if freq = 0 {

return nil

}

freqns := float64(freq) / 1e9

return func() time.Duration {

var now uint64

syscall.Syscall(qpc, 1, uintptr(unsafe.Pointer(now)), 0, 0)

return time.Duration(float64(now-start) / freqns)

}

}

var StopWatch func() time.Duration

if StopWatch = QPCTimer(); StopWatch == nil {

// Fallback implementation

start := time.Now()

StopWatch = func() time.Duration { return time.Since(start) }

}

return StopWatch

}

func main() {

// Call a new stop watch to create one from this moment on.

watch := NewStopWatch()

// Do some stuff that takes time.

time.Sleep(1)

// Call the stop watch itself and it will return a time.Duration

dur := watch()

}

這和語(yǔ)言沒(méi)關(guān)系,操作系統(tǒng)要提供這樣的原語(yǔ)。linux和windows都是可以的。

標(biāo)題名稱:go語(yǔ)言計(jì)時(shí)器 go語(yǔ)言定時(shí)任務(wù)
標(biāo)題路徑:http://vcdvsql.cn/article24/doicjce.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供自適應(yīng)網(wǎng)站面包屑導(dǎo)航移動(dòng)網(wǎng)站建設(shè)全網(wǎng)營(yíng)銷推廣品牌網(wǎng)站建設(shè)微信小程序

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

微信小程序開(kāi)發(fā)