中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

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

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Goland協程調度器scheduler如何實現

發布時間:2022-06-07 09:42:57 來源:億速云 閱讀:173 作者:zzz 欄目:開發技術

本篇內容主要講解“Goland協程調度器scheduler如何實現”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Goland協程調度器scheduler如何實現”吧!

1. 調度器scheduler的作用

我們都知道,在Go語言中,程序運行的最小單元是gorouines。

然而程序的運行最終都是要交給操作系統來執行的,以Java為例,Java中的一個線程對應的就是操作系統中的線程,以此來實現在操作系統中的運行。在Go中,gorouines比線程更輕量級,其與操作系統的線程也不是一一對應的關系,然而,最終我們想要執行程序,還是要借助操作系統的線程來完成,調度器scheduler的工作就是完成gorouines到操作系統線程的調度。

2. GMP模型

Goland協程調度器scheduler如何實現

當我們運行go fun(){}時,會生成一個g,優先放置在創建他的p的本地隊列中,如果本地隊列已滿,那么會放置在全局隊列中。

g的運行需要借助p與m,p是執行器,只有獲得p的g才能執行,p的執行需要掛在m上,m對應的是操作系統中的線程,p的數量與CPU的核數相同。

goroutine運行所需要的上下文信息都是存放在g的數據結構當中的,所以g可以依靠任意的p或者m執行,而對于操作系統而言,其并不能看到p與g的調度過程,這些過程對于操作系統線程來說都是連續的,所以省去了線程上下文切換的開銷。

g的數據結構如下所示:

type g struct {
    stack       stack   // g自己的棧

    m            *m      // 執行當前g的m
    sched        gobuf   // 保存了g的現場,goroutine切換時通過它來恢復
    atomicstatus uint32  // g的狀態Gidle,Grunnable,Grunning,Gsyscall,Gwaiting,Gdead
    goid         int64
    schedlink    guintptr // 下一個g, g鏈表

    preempt       bool //搶占標記

    lockedm        muintptr // 鎖定的M,g中斷恢復指定M執行
    gopc           uintptr  // 創建該goroutine的指令地址
    startpc        uintptr  // goroutine 函數的指令地址
}

p的數據結構如下所示:

type p struct {
    id          int32
    status      uint32 // 狀態
    link        puintptr // 下一個P, P鏈表
    m           muintptr // 擁有這個P的M
    mcache      *mcache  

    // P本地runnable狀態的G隊列
    runqhead uint32
    runqtail uint32
    runq     [256]guintptr
    
    runnext guintptr // 一個比runq優先級更高的runnable G

    // 狀態為dead的G鏈表,在獲取G時會從這里面獲取
    gFree struct {
        gList
        n int32
    }

    gcBgMarkWorker       guintptr // (atomic)
    gcw gcWork

}

m的數據結構如下所示:

type m struct {
    g0      *g     // g0, 每個M都有自己獨有的g0

    curg          *g       // 當前正在運行的g
    p             puintptr // 當前用于的p
    nextp         puintptr // 當m被喚醒時,首先擁有這個p
    id            int64
    spinning      bool // 是否處于自旋

    park          note
    alllink       *m // on allm
    schedlink     muintptr // 下一個m, m鏈表
    mcache        *mcache  // 內存分配
    lockedg       guintptr // 和 G 的lockedm對應
    freelink      *m // on sched.freem

}

通過gmp模型,我們能解決gorouines到操作系統線程的映射問題,gorouines之間的切換是在用戶態完成的,在操作系統的視角來看,線程的上下文切換并不頻繁,因此就少了很多陷入內核的過程,所以有更好的并發效果。

3. 調度機制

1)work stealing機制

當一個p上的g執行完之后,他會嘗試從其他的p隊列中竊取g來執行,以減少操作系統線程的切換動作。

2)hand off機制

這個是針對m來說的,有的時候m可能因為g的信號調用而被操作系統阻塞,這個時候p就會掛載去另一個m繼續執行可以執行的g,當阻塞的m就緒之后,會給p發信號,召喚他回來繼續進行后續操作。

到此,相信大家對“Goland協程調度器scheduler如何實現”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

柞水县| 富源县| 武安市| 平武县| 甘泉县| 萍乡市| 平潭县| 凤台县| 苏尼特右旗| 岚皋县| 乌拉特后旗| 麦盖提县| 长汀县| 临猗县| 大丰市| 邻水| 昌宁县| 普兰县| 抚顺县| 金门县| 新安县| 常宁市| 彭泽县| 吉水县| 安徽省| 克东县| 榆林市| 大埔区| 丰台区| 沧州市| 炎陵县| 阳春市| 莱芜市| 肃宁县| 西乡县| 汾西县| 长葛市| 嘉义县| 林州市| 叶城县| 张家口市|