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

Golang中獲取goroutine的ID的示例代碼

 更新時(shí)間:2025年06月12日 09:47:38   作者:左詩(shī)右碼  
在使用?Go?語(yǔ)言進(jìn)行并發(fā)編程時(shí),Goroutine?是一種輕量級(jí)線程,具有很高的性能優(yōu)勢(shì),本文將詳細(xì)介紹在?Go?語(yǔ)言中獲取?Goroutine?ID?的幾種方法,大家可以根據(jù)需要進(jìn)行選擇

在使用 Go 語(yǔ)言進(jìn)行并發(fā)編程時(shí),Goroutine 是一種輕量級(jí)線程,具有很高的性能優(yōu)勢(shì)。然而,Go 語(yǔ)言并未直接提供獲取 Goroutine ID 的官方 API。這是 Go 語(yǔ)言設(shè)計(jì)的一部分,目的是避免開(kāi)發(fā)者依賴 Goroutine ID 進(jìn)行不必要的復(fù)雜操作。然而,在某些場(chǎng)景下,獲取 Goroutine ID 可能會(huì)有助于調(diào)試和日志跟蹤。

本文將詳細(xì)介紹在 Go 語(yǔ)言中獲取 Goroutine ID 的幾種方法。

為什么需要 Goroutine ID?

在調(diào)試并發(fā)程序時(shí),了解某段代碼是由哪個(gè) Goroutine 執(zhí)行的,有助于:

  • 調(diào)試問(wèn)題:清楚地知道問(wèn)題來(lái)源。
  • 日志追蹤:區(qū)分不同 Goroutine 的執(zhí)行過(guò)程。
  • 性能分析:理解并發(fā)任務(wù)的執(zhí)行情況。

雖然這些需求合理,但 Go 語(yǔ)言希望開(kāi)發(fā)者更專注于 Goroutine 的邏輯而非它的標(biāo)識(shí)。因此,官方并未直接提供獲取 Goroutine ID 的功能。

獲取 Goroutine ID 的實(shí)現(xiàn)原理

其實(shí) Go 的每個(gè) Goroutine 都有一個(gè)唯一的標(biāo)識(shí)符,存儲(chǔ)在其運(yùn)行時(shí)的內(nèi)部結(jié)構(gòu)中。這個(gè) ID 不直接對(duì)外暴露,但我們可以通過(guò)間接手段獲取。

Go 的運(yùn)行時(shí)包 runtime 提供了一些工具來(lái)幫助我們了解 Goroutine 的狀態(tài),其中最常用的是 runtime.Stack。

runtime.Stack 可以生成當(dāng)前 Goroutine 的調(diào)用棧信息,這些信息中包含了 Goroutine 的 ID。通過(guò)解析調(diào)用棧的內(nèi)容,就能提取出 Goroutine 的 ID。

獲取 Goroutine ID

以下是一個(gè)獲取當(dāng)前 Goroutine ID 的簡(jiǎn)單實(shí)現(xiàn):

package main

import (
	"bytes"
	"fmt"
	"runtime"
	"strconv"
)

// GetGoroutineID 返回當(dāng)前 Goroutine 的 ID
// 通過(guò) runtime.Stack 獲取當(dāng)前 Goroutine 的棧信息,然后提取出 Goroutine ID
// 這種方式可以獲取到當(dāng)前 Goroutine 的 ID,但是性能較差
func GetGoroutineID() uint64 {
	var buf [64]byte
	// runtime.Stack(buf[:], false) 會(huì)將當(dāng)前 Goroutine 的棧信息寫(xiě)入 buf 中
	// 第二個(gè)參數(shù)是 false 表示只獲取當(dāng)前 Goroutine 的棧信息,如果為 true 則會(huì)獲取所有 Goroutine 的棧信息
	n := runtime.Stack(buf[:], false)
	stack := string(buf[:n])
	// fmt.Println("========")
	// fmt.Println(stack)
	// fmt.Println()
	// stack 樣例: "goroutine 7 [running]:\n..."
	// 提取 goroutine 后面的數(shù)字
	fields := bytes.Fields([]byte(stack))
	id, err := strconv.ParseUint(string(fields[1]), 10, 64)
	if err != nil {
		panic(fmt.Sprintf("無(wú)法解析 Goroutine ID: %v", err))
	}
	return id
}

func main() {
	fmt.Printf("Main Goroutine ID: %d\n", GetGoroutineID())

	var wg sync.WaitGroup
	for i := 0; i < 10; i++ {
		i := i
		wg.Add(1)
		go func() {
			defer wg.Done()
			fmt.Printf("Child [%d] Goroutine ID: [%d]\n", i, GetGoroutineID())
		}()
	}

	wg.Wait()
}

代碼解析

1.runtime.Stack 獲取調(diào)用棧

runtime.Stack 會(huì)返回當(dāng)前 Goroutine 的調(diào)用棧信息,包括 Goroutine 的 ID。

2.解析 Goroutine ID

調(diào)用棧信息是字符串形式,例如:

goroutine 7 [running]:

我們只需提取 goroutine 后面的數(shù)字,即可獲取 ID。

3.類型轉(zhuǎn)換

使用 strconv.ParseUint 將字符串 ID 轉(zhuǎn)換為數(shù)值類型,便于后續(xù)操作。

4.主 Goroutine 與子 Goroutine 的對(duì)比

main 函數(shù)中,我們分別打印主 Goroutine 和子 Goroutine 的 ID,以觀察它們的不同。

注意事項(xiàng)

性能影響

使用 runtime.Stack 獲取 Goroutine ID 的代價(jià)相對(duì)較高,僅適用于調(diào)試或日志場(chǎng)景,不建議在性能敏感的代碼中頻繁使用。

不依賴 ID 進(jìn)行業(yè)務(wù)邏輯

Goroutine ID 是一個(gè)內(nèi)部實(shí)現(xiàn)細(xì)節(jié),不應(yīng)在業(yè)務(wù)邏輯中依賴它,例如用于鎖定資源或同步任務(wù)。Go 鼓勵(lì)使用通道(channel)等高級(jí)并發(fā)原語(yǔ)來(lái)管理任務(wù)。

既然使用 runtime.Stack 先獲取堆棧信息的方式獲取 Goroutine ID 性能不高,那么有沒(méi)有更加高效的方式呢?

使用第三方包高效獲取

我們可以采用第三方包 github.com/petermattis/goid 來(lái)高效的獲取當(dāng)前 goroutine 的 ID

首先我們先安裝這個(gè)包

go get -u github.com/petermattis/goid

這個(gè)包使用起來(lái)也非常簡(jiǎn)單,直接

// goid 庫(kù)使用了 C 和 匯編來(lái)獲取 Goroutine ID,性能更好
func GetGoroutineID1() int64 {
	id := goid.Get()
	return id
}

goid 庫(kù)使用了 C 和匯編來(lái)獲取 goroutine ID,所以性能更好。并且 goid 對(duì)多個(gè) go 版本做了兼容,而且為了保證兼容性,我們通過(guò)查看 https://github.com/petermattis/goid/blob/master/goid.go 也可以發(fā)現(xiàn)提供了一個(gè) Go 語(yǔ)言版本的實(shí)現(xiàn)。這個(gè) Go 版本的實(shí)現(xiàn)也是通過(guò)使用 runtime.Stack() 來(lái)實(shí)現(xiàn)的。所以,如果你真的需要獲取 goroutine ID,那么還是比較推薦使用這個(gè)包的。

總結(jié)

Goroutine 是 Go 并發(fā)編程的核心,而 Goroutine ID 在某些場(chǎng)景下可以幫助我們更好地理解和調(diào)試代碼。盡管 Go 官方?jīng)]有提供直接的 API,但通過(guò) runtime.Stack,我們可以間接獲取到 Goroutine 的 ID。但是由于通過(guò) runtime.Stack 的方式去獲取 Goroutine ID 性能不高,因此如果你確確實(shí)實(shí)想要獲取 Goroutine ID 時(shí),就建議你直接使用 goid 包來(lái)獲取。

然而,獲取 ID 應(yīng)僅限于調(diào)試場(chǎng)景,在實(shí)際開(kāi)發(fā)中更應(yīng)關(guān)注 Goroutine 的行為和通道通信。

到此這篇關(guān)于Golang中獲取goroutine的ID的示例代碼的文章就介紹到這了,更多相關(guān)go獲取goroutine的id內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Golang中的泛型你真的了解嗎

    Golang中的泛型你真的了解嗎

    Golang?在?1.18?版本更新后引入了泛型,這是一個(gè)重要的更新,Gopher?萬(wàn)眾矚目,為?Golang?帶來(lái)了更多的靈活性和可重用性,今天,我們將深入探討泛型的概念、為什么需要泛型、泛型的語(yǔ)法,并探討如何在實(shí)踐中使用它
    2023-05-05
  • Go處理JSON數(shù)據(jù)的實(shí)現(xiàn)

    Go處理JSON數(shù)據(jù)的實(shí)現(xiàn)

    本文主要介紹了Go處理JSON數(shù)據(jù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • Go?1.21中引入的新包maps和cmp功能作用詳解

    Go?1.21中引入的新包maps和cmp功能作用詳解

    這篇文章主要為大家介紹了Go?1.21中引入的新包maps和cmp功能作用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-11-11
  • Go程序性能優(yōu)化及pprof使用方法詳解

    Go程序性能優(yōu)化及pprof使用方法詳解

    這篇文章主要為大家詳細(xì)介紹了Go程序性能優(yōu)化及pprof的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • 詳解Golang中interface接口的原理和使用技巧

    詳解Golang中interface接口的原理和使用技巧

    interface?接口在?Go?語(yǔ)言里面的地位非常重要,是一個(gè)非常重要的數(shù)據(jù)結(jié)構(gòu)。本文主要介紹了Golang中interface接口的原理和使用技巧,希望對(duì)大家有所幫助
    2022-11-11
  • 詳解go-zero是如何做路由管理的

    詳解go-zero是如何做路由管理的

    go-zero 是一個(gè)微服務(wù)框架,包含了 web 和 rpc 兩大部分,而對(duì)于 web 框架來(lái)說(shuō),路由管理是必不可少的一部分,那么本文就來(lái)探討一下 go-zero 的路由管理是怎么做的吧
    2023-08-08
  • Go使用Google?Gemini?Pro?API創(chuàng)建簡(jiǎn)單聊天機(jī)器人

    Go使用Google?Gemini?Pro?API創(chuàng)建簡(jiǎn)單聊天機(jī)器人

    這篇文章主要為大家介紹了Go使用Google?Gemini?Pro?API創(chuàng)建簡(jiǎn)單聊天機(jī)器人實(shí)現(xiàn)過(guò)程詳解,本文將通過(guò)最新的gemini?go?sdk來(lái)實(shí)現(xiàn)命令行聊天機(jī)器人
    2023-12-12
  • Go打印結(jié)構(gòu)體提升代碼調(diào)試效率實(shí)例詳解

    Go打印結(jié)構(gòu)體提升代碼調(diào)試效率實(shí)例詳解

    這篇文章主要介紹了Go打印結(jié)構(gòu)體提升代碼調(diào)試效率實(shí)例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2024-02-02
  • 詳解Go語(yǔ)言中配置文件使用與日志配置

    詳解Go語(yǔ)言中配置文件使用與日志配置

    這篇文章主要為大家詳細(xì)講解一下Go語(yǔ)言中調(diào)整項(xiàng)目目錄結(jié)構(gòu)、增加配置文件使用和增加日志配置的方法,文中示例代碼講解詳細(xì),需要的可以參考一下
    2022-06-06
  • golang如何設(shè)置Header Content-type

    golang如何設(shè)置Header Content-type

    這篇文章主要介紹了golang如何設(shè)置Header Content-type問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-01-01

最新評(píng)論