亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

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

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

前言:

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

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

1、作用:

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

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

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

package main

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

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

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

② 垃圾回收:

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

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

③ 棧和堆操作:

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

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

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

⑤ 錯(cuò)誤處理:

runtime包提供了獲取調(diào)用棧信息、根據(jù)PC地址獲取函數(shù)信息等函數(shù),用于錯(cuò)誤處理和調(diào)試時(shí)追蹤錯(cuò)誤發(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)操作,如獲取可同時(shí)執(zhí)行的最大P數(shù)目、綁定goroutine到特定的P等。

⑦ 信號(hào)處理:

runtime包提供了處理C語(yǔ)言信號(hào)的函數(shù),用于和外部C庫(kù)進(jìn)行交互時(shí)的信號(hào)處理。

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

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

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

① Goroutine相關(guān):

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

② 垃圾回收:

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

③ 棧:

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

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

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

⑤ 并發(fā)控制:

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

(等)

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

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

① runtime.Gosched():讓出CPU時(shí)間片,重新等待安排任務(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運(yùn)行時(shí)的調(diào)度器使用GOMAXPROCS參數(shù)來(lái)確定需要使用多少個(gè)OS線程來(lái)同時(shí)執(zhí)行Go代碼。默認(rèn)值是機(jī)器上的CPU核心數(shù)。例如在一個(gè)8核心的機(jī)器上,調(diào)度器會(huì)把Go代碼同時(shí)調(diào)度到8個(gè)OS線程上(GOMAXPROCS是m:n調(diào)度中的n)。

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

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

可以通過(guò)將任務(wù)分配到不同的CPU邏輯核心上實(shí)現(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)
}

兩個(gè)任務(wù)只有一個(gè)邏輯核心,此時(shí)是做完一個(gè)任務(wù)再做另一個(gè)任務(wù)。 將邏輯核心數(shù)設(shè)為2,此時(shí)兩個(gè)任務(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è)計(jì):

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

3、運(yùn)行時(shí)類型信息與反射支持

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

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

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

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

4、runtime包與開(kāi)發(fā)者實(shí)踐

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

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

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

總結(jié) 

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

相關(guān)文章

最新評(píng)論