登录
首页 >  Golang >  Go问答

如何获得 Goroutine 的标识符?

来源:stackoverflow

时间:2024-02-22 11:21:24 164浏览 收藏

今天golang学习网给大家带来了《如何获得 Goroutine 的标识符?》,其中涉及到的知识点包括等等,无论你是小白还是老手,都适合看一看哦~有好的建议也欢迎大家在评论留言,若是看完有所收获,也希望大家能多多点赞支持呀!一起加油学习~

问题内容

如何获取 goroutine 的运行时 id?

我从导入的包中获取交错日志 - 一种方法是向每个 goroutine 的日志添加唯一标识符。

我发现了一些对 runtime.goid 的引用:

func worker() {
    id := runtime.GoID()
    log.Println("Goroutine ID:", id)
}

但看起来现在已经过时/已被删除 - https://pkg.go.dev/runtime?


正确答案


go 故意选择不提供 id,因为这会鼓励更糟糕的软件并损害整个生态系统:https: //go.dev/doc/faq#no_goroutine_id

一般来说,去匿名化 goroutine 的愿望是一个设计缺陷,强烈不建议这样做。几乎总会有更好的方法来解决手头的问题。例如,如果您需要唯一标识符,则应将其传递到函数中或可能通过 context.context 传递。

但是,运行时内部需要 id 来实现。出于教育目的,您可以通过以下方式找到它们:

package main

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

func main() {
    fmt.println(goid())

    done := make(chan struct{})
    go func() {
        fmt.println(goid())
        done <- struct{}{}
    }()
    go func() {
        fmt.println(goid())
        done <- struct{}{}
    }()
    <-done
    <-done
}

var (
    goroutineprefix = []byte("goroutine ")
    errbadstack     = errors.new("invalid runtime.stack output")
)

// this is terrible, slow, and should never be used.
func goid() (int, error) {
    buf := make([]byte, 32)
    n := runtime.stack(buf, false)
    buf = buf[:n]
    // goroutine 1 [running]: ...

    buf, ok := bytes.cutprefix(buf, goroutineprefix)
    if !ok {
        return 0, errbadstack
    }

    i := bytes.indexbyte(buf, ' ')
    if i < 0 {
        return 0, errbadstack
    }

    return strconv.atoi(string(buf[:i]))
}

示例输出:

1 
19 
18 

也可以通过访问 g 结构中的 goid 字段来通过程序集找到它们(不太可移植)。这就是像 github.com/petermattis/goid 这样的包通常是这样做的。

今天关于《如何获得 Goroutine 的标识符?》的内容就介绍到这里了,是不是学起来一目了然!想要了解更多关于的内容请关注golang学习网公众号!

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>