欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Go學(xué)習(xí)記錄之runtime包深入解析

 更新時間:2025年06月10日 11:49:41   作者:jiajixi  
Go語言runtime包管理運行時環(huán)境,涵蓋goroutine調(diào)度、內(nèi)存分配、垃圾回收、類型信息等核心功能,這篇文章主要介紹了Go學(xué)習(xí)記錄之runtime包的相關(guān)資料,文中通過代碼介紹的非常詳細,需要的朋友可以參考下

前言:

先前學(xué)習(xí)到goroutine協(xié)程與channel調(diào)節(jié)并發(fā)同步時,有涉及到關(guān)于runtime包管理goroutine運行時的知識點。由于沒有接觸過,并且出于goroutine的重要性(runtime聽著很高大上)的原因,通過多方學(xué)習(xí)并博客記錄。

一、runtime包內(nèi)容學(xué)習(xí)

1、作用:

其作用主要是與程序的運行時環(huán)境進行交互,提供了一系列函數(shù)和變量,用于控制、管理和監(jiān)視程序的執(zhí)行:

① Goroutine和并發(fā)控制:

runtime包提供了一些函數(shù)來管理goroutine,如創(chuàng)建和銷毀goroutine、設(shè)置最大可同時執(zhí)行的CPU數(shù)目等,以及用于并發(fā)控制的函數(shù),如讓出CPU時間片、鎖定和解鎖goroutine到線程等。

package main

import (
    "fmt"
    "runtime"
    "time"
)

func worker() {
    defer fmt.Println("Worker exiting")
    runtime.Gosched() // 主動讓出 CPU
    fmt.Println("Worker running")
}

func main() {
    go worker()
    time.Sleep(time.Second)
    fmt.Println("Number of goroutines:", runtime.NumGoroutine())
}

② 垃圾回收:

Go語言使用自動垃圾回收機制來管理內(nèi)存,runtime包提供了手動觸發(fā)垃圾回收、設(shè)置垃圾回收的百分比、獲取內(nèi)存統(tǒng)計信息等函數(shù),用于對垃圾回收進行調(diào)控和監(jiān)測。

func main() {
    var m runtime.MemStats
    runtime.ReadMemStats(&m)
    fmt.Printf("Allocated memory: %d bytes\n", m.Alloc)
    runtime.GC() // 手動觸發(fā) GC
    runtime.ReadMemStats(&m)
    fmt.Printf("After GC: %d bytes\n", m.Alloc)
}

③ 棧和堆操作:

runtime包提供了函數(shù)來獲取當(dāng)前goroutine的堆棧信息、完整的堆棧跟蹤,以及對堆棧進行分析和剖析的相關(guān)函數(shù)。

④ 系統(tǒng)信息和調(diào)試:

runtime包提供了獲取CPU核心數(shù)、CPU性能分析、調(diào)試信息等函數(shù),可以用于獲取關(guān)于系統(tǒng)的一些基本信息和進行程序的調(diào)試。

⑤ 錯誤處理:

runtime包提供了獲取調(diào)用棧信息、根據(jù)PC地址獲取函數(shù)信息等函數(shù),用于錯誤處理和調(diào)試時追蹤錯誤發(fā)生的位置。

func printStack() {
    var buf [4096]byte
    n := runtime.Stack(buf[:], false)
    fmt.Printf("Stack trace:\n%s\n", string(buf[:n]))
}

func main() {
    defer printStack()
    panic("Something went wrong!")
}

⑥ P操作:

runtime包提供了與處理器(P)的相關(guān)操作,如獲取可同時執(zhí)行的最大P數(shù)目、綁定goroutine到特定的P等。

⑦ 信號處理:

runtime包提供了處理C語言信號的函數(shù),用于和外部C庫進行交互時的信號處理。

通過使用runtime包提供的函數(shù)和變量,可以更控制程序的運行時行為、優(yōu)化性能、處理錯誤和調(diào)試問題。但需要注意,對runtime包過度依賴可能會降低代碼的可移植性

2、相關(guān)函數(shù):

runtime包提供了與程序運行時環(huán)境交互的函數(shù)和變量,包含了與上述作用相關(guān)的函數(shù):

① Goroutine相關(guān):

goexit():終止當(dāng)前goroutine的執(zhí)行。
GOMAXPROCS(n int):設(shè)置可同時執(zhí)行的最大CPU數(shù)。
NumGoroutine():返回當(dāng)前存在的goroutine數(shù)目。

② 垃圾回收:

GC(): 手動觸發(fā)垃圾回收。
SetFinalizer(obj interface{}, finalizer interface{}):為對象設(shè)置一個垃圾回收的終結(jié)器(finalizer),當(dāng)對象被垃圾回收時,終結(jié)器會被調(diào)用。

③ 棧:

Stack(buf []byte, all bool): 返回當(dāng)前goroutine的堆棧信息。
StackTrace(p *Profiling)::返回當(dāng)前程序的完整堆棧跟蹤。

④ 內(nèi)存統(tǒng)計:

ReadMemStats(m *MemStats): 獲取當(dāng)前程序的內(nèi)存使用統(tǒng)計信息。

⑤ 并發(fā)控制:

LockOSThread(): 鎖定當(dāng)前goroutine到當(dāng)前線程上。
UnlockOSThread(): 解除當(dāng)前goroutine對當(dāng)前線程的鎖定。

(等)

同樣的,由于其對底層進行交互,過多使用相關(guān)函數(shù)也會降低可移植性,開發(fā)過程中需要注意。

3、幾個較為重要的函數(shù):

① runtime.Gosched():讓出CPU時間片,重新等待安排任務(wù)

package main

import (
    "fmt"
    "runtime"
)

func main() {
    go func(s string) {
        for i := 0; i < 2; i++ {
            fmt.Println(s)
        }
    }("world")
    // 主協(xié)程
    for i := 0; i < 2; i++ {
        // 切一下,再次分配任務(wù)
        runtime.Gosched()
        fmt.Println("hello")
    }
}

② runtime.Goexit():退出當(dāng)前協(xié)程

package main

import (
    "fmt"
    "runtime"
)

func main() {
    go func() {
        defer fmt.Println("A.defer")
        func() {
            defer fmt.Println("B.defer")
            // 結(jié)束協(xié)程
            runtime.Goexit()
            defer fmt.Println("C.defer")
            fmt.Println("B")
        }()
        fmt.Println("A")
    }()
    for {
    }
}

③ runtime.GOMAXPROCS:

Go運行時的調(diào)度器使用GOMAXPROCS參數(shù)來確定需要使用多少個OS線程來同時執(zhí)行Go代碼。默認值是機器上的CPU核心數(shù)。例如在一個8核心的機器上,調(diào)度器會把Go代碼同時調(diào)度到8個OS線程上(GOMAXPROCS是m:n調(diào)度中的n)。

Go語言中可以通過runtime.GOMAXPROCS()函數(shù)設(shè)置當(dāng)前程序并發(fā)時占用的CPU邏輯核心數(shù)。

Go1.5版本之前,默認使用的是單核心執(zhí)行。Go1.5版本之后,默認使用全部的CPU邏輯核心數(shù)。

可以通過將任務(wù)分配到不同的CPU邏輯核心上實現(xiàn)并行的效果

func a() {
    for i := 1; i < 10; i++ {
        fmt.Println("A:", i)
    }
}

func b() {
    for i := 1; i < 10; i++ {
        fmt.Println("B:", i)
    }
}

func main() {
    runtime.GOMAXPROCS(1)
    go a()
    go b()
    time.Sleep(time.Second)
}

兩個任務(wù)只有一個邏輯核心,此時是做完一個任務(wù)再做另一個任務(wù)。 將邏輯核心數(shù)設(shè)為2,此時兩個任務(wù)并行執(zhí)行,代碼如下。

func a() {
    for i := 1; i < 10; i++ {
        fmt.Println("A:", i)
    }
}

func b() {
    for i := 1; i < 10; i++ {
        fmt.Println("B:", i)
    }
}

func main() {
    runtime.GOMAXPROCS(2)
    go a()
    go b()
    time.Sleep(time.Second)
}

二、底層設(shè)計:

Go語言的高效與簡潔,離不開其運行時環(huán)境。runtime包作為Go語言運行時系統(tǒng)的核心接口,承載著內(nèi)存管理、協(xié)程調(diào)度、垃圾回收、類型信息處理等關(guān)鍵功能。深入理解runtime包的底層設(shè)計,可以深入了解Go語言的運行機制。

1、內(nèi)存管理與垃圾回收的底層協(xié)作

① 內(nèi)存分配策略

runtime包中的內(nèi)存分配器采用分層設(shè)計,分為線程緩存(Thread Cache)、中心緩存(Central Cache)和堆(Heap)三個層級:

• 線程緩存:每個Go線程擁有獨立的線程緩存,用于快速分配小對象(通常小于16字節(jié)),避免頻繁訪問全局資源,減少鎖競爭;

• 中心緩存:作為線程緩存的補充,負責(zé)從堆中獲取大塊內(nèi)存,并切割成適合線程緩存的小塊,平衡各線程間的內(nèi)存使用;

• 堆:內(nèi)存分配的最終來源,由垃圾回收器統(tǒng)一管理,當(dāng)線程緩存和中心緩存無法滿足需求時,直接從堆中分配內(nèi)存 。

② 垃圾回收協(xié)同工作

垃圾回收器(GC)與內(nèi)存分配器緊密配合,runtime包通過一系列函數(shù)控制GC的行為,如runtime.GC()可手動觸發(fā)垃圾回收。在GC過程中:

• 標記階段:從根對象(如全局變量、棧上變量)出發(fā),標記所有可達對象;

• 清除階段:回收未被標記的對象,將其占用的內(nèi)存歸還到空閑列表;

• 整理階段(可選):在特定情況下,對堆內(nèi)存進行整理,減少內(nèi)存碎片 。

2、協(xié)程調(diào)度的底層實現(xiàn)細節(jié)

runtime包是協(xié)程調(diào)度的核心執(zhí)行者,基于M:N調(diào)度模型實現(xiàn)高效的協(xié)程調(diào)度:

• Goroutine(G):用戶態(tài)的輕量級線程,是Go語言并發(fā)的基本單元;

• Machine(M):對應(yīng)操作系統(tǒng)線程,負責(zé)執(zhí)行Goroutine中的代碼;

• Processor(P):協(xié)程調(diào)度的關(guān)鍵組件,維護本地協(xié)程隊列,綁定到M上以減少上下文切換開銷。

調(diào)度過程中,runtime包通過以下機制確保協(xié)程高效運行:

• 本地隊列優(yōu)先:P優(yōu)先從本地隊列獲取Goroutine執(zhí)行,減少競爭;

• 工作竊取算法:當(dāng)本地隊列為空時,P從其他P的本地隊列竊取Goroutine,均衡負載;

• 阻塞處理:當(dāng)M執(zhí)行的Goroutine發(fā)生阻塞(如I/O操作),M與P分離,P綁定到其他空閑M繼續(xù)執(zhí)行其他Goroutine,避免線程浪費 。

3、運行時類型信息與反射支持

runtime包管理著程序中所有類型的元數(shù)據(jù),這些信息是反射功能的基礎(chǔ):

• 類型描述:通過結(jié)構(gòu)體記錄類型的大小、對齊方式、方法集合等信息,如rtype結(jié)構(gòu)體存儲類型的基本屬性,itab結(jié)構(gòu)體記錄接口類型與具體實現(xiàn)類型的映射關(guān)系;

• 反射實現(xiàn):reflect包依賴runtime包提供的類型信息,在運行時動態(tài)獲取對象的類型、調(diào)用方法、修改屬性 。

例如,在進行反射操作時,runtime包負責(zé)提供類型比較、方法查找等底層支持,確保反射操作的正確性和高效性。

4、runtime包與開發(fā)者實踐

雖然runtime包的大部分功能在幕后自動運行,但開發(fā)者在某些場景下仍需關(guān)注其行為:

• 性能調(diào)優(yōu):通過runtime.GOMAXPROCS()設(shè)置處理器數(shù)量,優(yōu)化協(xié)程調(diào)度效率;利用runtime/pprof包進行性能分析,定位內(nèi)存泄漏、CPU瓶頸等問題;

• 特殊場景處理:在需要與操作系統(tǒng)深度交互時,使用runtime包提供的系統(tǒng)調(diào)用接口;在編寫高性能程序時,通過runtime包的內(nèi)存分配函數(shù)手動管理內(nèi)存 。

總結(jié) 

到此這篇關(guān)于Go學(xué)習(xí)記錄之runtime包深入解析的文章就介紹到這了,更多相關(guān)Go runtime包內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang命令行進行debug調(diào)試操作

    Golang命令行進行debug調(diào)試操作

    今天小編就為大家分享一篇關(guān)于,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-04-04
  • golang開發(fā)微框架Gin的安裝測試及簡介

    golang開發(fā)微框架Gin的安裝測試及簡介

    這篇文章主要為大家介紹了golang微框架Gin的安裝測試及簡介,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步早日升職加薪
    2021-11-11
  • 基于golang的簡單分布式延時隊列服務(wù)的實現(xiàn)

    基于golang的簡單分布式延時隊列服務(wù)的實現(xiàn)

    這篇文章主要介紹了基于golang的簡單分布式延時隊列服務(wù)的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • Go 1.21新增的slices包中切片函數(shù)用法詳解

    Go 1.21新增的slices包中切片函數(shù)用法詳解

    Go 1.21新增的 slices 包提供了很多和切片相關(guān)的函數(shù),可以用于任何類型的切片,本文通過代碼示例為大家介紹了部分切片函數(shù)的具體用法,感興趣的小伙伴可以了解一下
    2023-08-08
  • golang 如何獲取pem格式RSA公私鑰長度

    golang 如何獲取pem格式RSA公私鑰長度

    這篇文章主要介紹了golang 如何獲取pem格式RSA公私鑰長度操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • Golang基于epoll實現(xiàn)最簡單網(wǎng)絡(luò)通信框架

    Golang基于epoll實現(xiàn)最簡單網(wǎng)絡(luò)通信框架

    這篇文章主要為大家詳細介紹了Golang如何基于epoll實現(xiàn)最簡單網(wǎng)絡(luò)通信框架,文中的示例代碼講解詳細,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)學(xué)習(xí)
    2023-06-06
  • golang實踐-第三方包為私有庫的配置方案

    golang實踐-第三方包為私有庫的配置方案

    這篇文章主要介紹了golang實踐-第三方包為私有庫的配置方案,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05
  • golang?cache帶索引超時緩存庫實戰(zhàn)示例

    golang?cache帶索引超時緩存庫實戰(zhàn)示例

    這篇文章主要為大家介紹了golang?cache帶索引超時緩存庫實戰(zhàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-09-09
  • Go語言制作svg格式樹形圖的示例代碼

    Go語言制作svg格式樹形圖的示例代碼

    SVG是可伸縮矢量圖形?(Scalable?Vector?Graphics),于2003年1月14日成為?W3C?推薦標準。本文將利用Go語言實現(xiàn)制作svg格式樹形圖,感興趣的可以了解一下
    2022-09-09
  • golang 實現(xiàn)并發(fā)求和

    golang 實現(xiàn)并發(fā)求和

    這篇文章主要介紹了golang 并發(fā)求和的實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-05-05

最新評論