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

淺談Golang的Work Stealing機(jī)制

 更新時間:2025年03月04日 10:25:17   作者:Lzww0608  
Go的運(yùn)行時系統(tǒng)使用了一種名為Work Stealing的調(diào)度策略來分配Goroutine到可用線程上執(zhí)行,本文主要介紹了淺談Golang的Work Stealing機(jī)制,具有一定的參考價值,感興趣的可以了解一下

Go的運(yùn)行時系統(tǒng)使用了一種名為Work Stealing(工作竊取)的調(diào)度策略來分配Goroutine到可用線程(稱為M,即Machine)上執(zhí)行。這樣可以最大化CPU使用率,減少任務(wù)調(diào)度的開銷。在這種機(jī)制下,任務(wù)隊列和調(diào)度器通過動態(tài)平衡負(fù)載來提高并發(fā)性能和吞吐量。

Go的調(diào)度器使用了P(Processor)與M和Goroutine進(jìn)行交互。每個P都維護(hù)了一個本地的Goroutine隊列,新創(chuàng)建的Goroutine首先會被放入創(chuàng)建它的P的本地隊列中。在這個系統(tǒng)中,P可以看作是可調(diào)度Goroutine的數(shù)量,每個P都可以關(guān)聯(lián)一個M來執(zhí)行Goroutine。

Work Stealing 機(jī)制的核心思想:每個操作系統(tǒng)線程(M)都有一個本地任務(wù)隊列,它會盡可能地先執(zhí)行自己隊列中的協(xié)程。當(dāng)某個M的P隊列為空,而其他P仍有任務(wù)時,該M會嘗試從其他P中"偷"一些協(xié)程來執(zhí)行,以實現(xiàn)負(fù)載均衡

基本工作原理

  • 任務(wù)隊列:每個工作線程(或goroutine)都有自己的雙端隊列(deque),用于存儲任務(wù)。當(dāng)一個線程生成新任務(wù)時,它會將任務(wù)放入自己的隊列。這種隊列就是上述所講的P處理器。

  • 執(zhí)行任務(wù):M首先從自己對應(yīng)P中獲取任務(wù)并執(zhí)行。如果它的任務(wù)隊列為空,它就會嘗試從其他線程的任務(wù)隊列P中竊取任務(wù)。

  • 竊取任務(wù):當(dāng)一個M發(fā)現(xiàn)自己的任務(wù)隊列P為空時,它會隨機(jī)選擇其他M的任務(wù)隊列P,從隊列的另一端竊取任務(wù)。這樣可以避免競爭,因為線程對自己的任務(wù)隊列使用一端,而其他線程只能從另一端竊取任務(wù)。

  • 負(fù)載均衡:通過這種機(jī)制,系統(tǒng)能夠動態(tài)地平衡負(fù)載。如果某個線程的任務(wù)較多,其他空閑線程可以幫助處理這些任務(wù),從而避免某些線程過載而其他線程空閑的情況。

  • 全局隊列:如果所有本地隊列P都為空,調(diào)度器會從全局隊列中獲取任務(wù),全局隊列存儲的是所有P都無法處理的goroutine。

以下是一個簡化的示意圖,展示了P, M和Goroutine的交互:

     P1       P2       P3
     |        |        |
     v        v        v
    [G1,G2] [G3]   [G4,G5,G6] 
     ^        ^        ^
     |        |        |
     M1       M2       M3

在這個圖中,我們有3個P(P1、P2和P3),每個P都有一個本地的Goroutine隊列。M1、M2和M3是3個線程,每個線程都關(guān)聯(lián)了一個P,并且從其隊列中取出Goroutine來執(zhí)行。當(dāng)M1完成了G1后,它會從P1的隊列中取出G2來執(zhí)行。如果P1的隊列為空,M1就會嘗試從P2或P3的隊列中”竊取”一個Goroutine。

當(dāng)從本線程M 從綁定 P 本地 隊列、全局G隊列、Netpoller 都找不到可執(zhí)行的 G,會從其它 P 里竊取G并放到當(dāng)前P上面

1)如果全局隊列有G,從全局隊列竊取的G數(shù)量:N = min(len(GRQ)/GOMAXPROCS + 1, len(GRQ/2)) (根據(jù)GOMAXPROCS數(shù)量負(fù)載均衡)

2)如果 Netpoller 有G(網(wǎng)絡(luò)IO被阻塞的G),從Netpoller竊取的G數(shù)量:N = 1

3)如果從其它P里竊取G,從其它P竊取的G數(shù)量:N = len(LRQ)/2(平分負(fù)載均衡)

4)如果嘗試多次一直找不到需要運(yùn)行的goroutine則進(jìn)入睡眠狀態(tài),等待被其它工作線程喚醒

從其它P竊取G的源碼見runtime/proc.go stealWork函數(shù),竊取流程如下:

1)選擇要竊取的P

2)從P中偷走一半G

選擇要竊取的P

竊取的實質(zhì)就是遍歷所有P,查看其運(yùn)行隊列是否有g(shù)oroutine,如果有,則取其一半到當(dāng)前工作線程的運(yùn)行隊列

為了保證公平性,遍歷P時并不是按照數(shù)組下標(biāo)順序訪問P,而是使用了一種偽隨機(jī)的方式遍歷allp中的每個P,防止每次遍歷時使用同樣的順序訪問allp中的元素

offset := uint32(random()) % nprocs
coprime := 隨機(jī)選取一個小于nprocs且與nprocs互質(zhì)的數(shù)
const stealTries = 4 // 最多重試4次
for i := 0; i < stealTries; i++ {
  // 隨機(jī)訪問所有 P
    for i := 0; i < nprocs; i++ {
        p := allp[offset]
        從p的運(yùn)行隊列偷取goroutine
        if 偷取成功 {
        break
        }
        offset += coprime
        offset = offset % nprocs
     }
}

可以看到只要隨機(jī)數(shù)不一樣,遍歷P的順序也不一樣,但可以保證經(jīng)過nprocs次循環(huán),每個P都會被訪問到

從P中偷走一半G

挑選出盜取的對象P之后,則調(diào)用 runtime/proc.go 函數(shù)runqsteal 盜取P的運(yùn)行隊列中的goroutine,runqsteal函數(shù)再調(diào)用runqgrap從P的本地隊列尾部批量偷走一半的 G

func runqgrab(_p_ *p, batch *[256]guintptr, batchHead uint32, stealRunNextG bool) uint32 {
    for {
        h := atomic.LoadAcq(&_p_.runqhead) // load-acquire, synchronize with other consumers
        t := atomic.LoadAcq(&_p_.runqtail) // load-acquire, synchronize with the producer
        n := t - h        //計算隊列中有多少個goroutine
        n = n - n/2     //取隊列中g(shù)oroutine個數(shù)的一半
        if n == 0 {
            ......
            return ......
        }
        return n
    }
}

優(yōu)點

  • 高效利用資源:通過動態(tài)平衡負(fù)載,確保所有線程盡可能地保持忙碌狀態(tài),提高CPU利用率。

  • 減少競爭:竊取任務(wù)時,只訪問其他線程隊列的一端,減少了競爭和鎖的使用。

  • 靈活性:能夠自適應(yīng)負(fù)載變化,當(dāng)任務(wù)量不均時,自動進(jìn)行負(fù)載均衡。

到此這篇關(guān)于淺談Golang的Work Stealing機(jī)制的文章就介紹到這了,更多相關(guān)Golang的Work Stealing機(jī)制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家! 

相關(guān)文章

  • go實現(xiàn)一個分布式限流器的方法步驟

    go實現(xiàn)一個分布式限流器的方法步驟

    項目中需要對api的接口進(jìn)行限流,本文主要介紹了go實現(xiàn)一個分布式限流器的方法步驟,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-01-01
  • Go語言并發(fā)定時任務(wù)之從Sleep到Context的8種寫法全解析

    Go語言并發(fā)定時任務(wù)之從Sleep到Context的8種寫法全解析

    這篇文章主要為大家詳細(xì)介紹了Go語言并發(fā)定時任務(wù)之從Sleep到Context的8種寫法的相關(guān)知識,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下
    2025-08-08
  • golang中的string與其他格式數(shù)據(jù)的轉(zhuǎn)換方法詳解

    golang中的string與其他格式數(shù)據(jù)的轉(zhuǎn)換方法詳解

    這篇文章主要介紹了golang中的string與其他格式數(shù)據(jù)的轉(zhuǎn)換方法,文章通過代碼示例介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-10-10
  • Golang并發(fā)編程中Context包的使用與并發(fā)控制

    Golang并發(fā)編程中Context包的使用與并發(fā)控制

    Golang的context包提供了在并發(fā)編程中傳遞取消信號、超時控制和元數(shù)據(jù)的功能,本文就來介紹一下Golang并發(fā)編程中Context包的使用與并發(fā)控制,感興趣的可以了解一下
    2024-11-11
  • golang中range在slice和map遍歷中的注意事項

    golang中range在slice和map遍歷中的注意事項

    今天小編就為大家分享一篇關(guān)于golang中range在slice和map遍歷中的注意事項,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • golang實現(xiàn)給圖片加水印

    golang實現(xiàn)給圖片加水印

    這篇文章主要為大家詳細(xì)介紹了Vue3如何利用golang實現(xiàn)給圖片加水印,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,需要的可以參考一下
    2023-12-12
  • Go語言防范SQL注入CSRF及XSS攻擊實例探究

    Go語言防范SQL注入CSRF及XSS攻擊實例探究

    在本文中,我們將會介紹幾種最常見的攻擊類型,并且介紹如何使用Golang來防范這些攻擊,本文會涉及XSS攻擊、CSRF攻擊、SQL注入等,如果你想學(xué)習(xí)Golang和網(wǎng)絡(luò)安全的相關(guān)知識,那么這篇文章會是一個很好的開始
    2024-01-01
  • Go語言實現(xiàn)權(quán)重抽獎系統(tǒng)的項目實踐

    Go語言實現(xiàn)權(quán)重抽獎系統(tǒng)的項目實踐

    本文主要介紹了Go語言實現(xiàn)權(quán)重抽獎系統(tǒng)的項目實踐,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-04-04
  • Go 中實現(xiàn)超時控制的方案

    Go 中實現(xiàn)超時控制的方案

    這篇文章主要介紹了Go 里的超時控制實現(xiàn)方案,本文給大家?guī)韮煞N解決方案,第一種方案是 Time.After(d Duration),第二種方案是利用 context,go 的 context 功能強(qiáng)大,本文通過實例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2021-10-10
  • Go語言隊列的四種實現(xiàn)及使用場景

    Go語言隊列的四種實現(xiàn)及使用場景

    本文主要介紹了Go語言隊列的四種實現(xiàn)及使用場景,包括切片、鏈表、帶鎖隊列和Channel,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2025-09-09

最新評論

明星| 武邑县| 农安县| 山西省| 集贤县| 崇州市| 固原市| 偏关县| 杭锦旗| 云林县| 吉安县| 鹤山市| 锡林郭勒盟| 垦利县| 龙州县| 淮北市| 大悟县| 宾阳县| 中方县| 汕头市| 舒城县| 常州市| 安平县| 青河县| 延川县| 河源市| 武义县| 新巴尔虎右旗| 平远县| 金华市| 三河市| 开江县| 句容市| 措勤县| 攀枝花市| 大渡口区| 海林市| 屏边| 新密市| 娱乐| 扬中市|