【问题标题】:How to identify a goroutine?如何识别 goroutine?
【发布时间】:2014-12-08 07:10:33
【问题描述】:

假设我有一堆 goroutines 的堆栈跟踪,例如。 g.:

goroutine 5633 [select]:
net/http.(*persistConn).writeLoop(0xc21303ac00)
    /usr/lib/go/src/pkg/net/http/transport.go:791 +0x271
created by net/http.(*Transport).dialConn
    /usr/lib/go/src/pkg/net/http/transport.go:529 +0x61e

在我的例子中,一个独特的特定于应用程序的对象由一组 goroutines 提供服务,我想查看与特定对象相关的 goroutines 的堆栈跟踪。我有数百个特定于应用程序的对象,所以我得到了数百个相同的 goroutine。

如何将我的日志与堆栈跟踪中的 goroutine 关联起来?似乎没有办法在堆栈跟踪中识别当前的 goroutine,也没有办法命名 goroutine,所以我可以在堆栈跟踪中看到特定的值。

PS

我已经阅读了 Go 邮件列表上的相关Why-would-you-want-to-it 帖子,因此我正在寻找替代方案/黑客/解决方法(希望不涉及洒代码每隔一行进行一次日志调用)。

【问题讨论】:

    标签: go goroutine


    【解决方案1】:

    workaround 是可能的,并且涉及一小段 C 代码。

    goid.c

    #include <runtime.h>
    void ·GetGoID(int32 ret) {
        ret = g->goid;
        USED(&ret);
    }
    

    main.go

    package main
    import (
        "fmt"
        "sync"
    )
    // Declaration is required
    func GetGoID() int32
    func main() {
        var wg sync.WaitGroup
        f := func() {
            wg.Add(1)
            go func() {
                fmt.Printf("goroutine %d\n", GetGoID())
                wg.Done()
            }()
        }
        for i := 0; i < 10; i++ {
            f()
        }
        wg.Wait()
    }
    

    构建并运行

    $ go build
    $ ./example
    goroutine 20
    goroutine 21
    goroutine 22
    goroutine 23
    goroutine 24
    goroutine 25
    goroutine 26
    goroutine 27
    goroutine 28
    goroutine 29
    

    【讨论】:

    【解决方案2】:

    Play

    这个方法比@Alex B 简单。它使用 debug.Stack() 以字节片的形式返回堆栈跟踪,其中包含 goroutine 在第二个字边界中的 id 以及堆栈跟踪。并解析它。

    package main
    
    import (
        "bytes"
        "fmt"
        "runtime/debug"
        "sync"
    )
    
    func main() {
        w := sync.WaitGroup{}
        w.Add(1)
        go func() {
            gr := bytes.Field(debug.Stack())[1]
            fmt.Println(string(gr))
            w.Done()
        }()
        w.Wait()
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-29
      • 2022-01-18
      • 1970-01-01
      • 2017-01-22
      • 2010-11-12
      • 2012-10-29
      • 2011-12-11
      • 2014-04-27
      相关资源
      最近更新 更多