-2

Go FAQ answers the question, "Why is there no goroutine ID?"

Goroutines do not have names; they are just anonymous workers. They expose no unique identifier, name, or data structure to the programmer.

https://go.dev/doc/faq#no_goroutine_id

I am not convinced by the explanation "They expose no unique identifier" because it appears that we can get goroutine id by using runtime.Stack().

Question

  1. What's the difference between "unique identifier" in Go FAQ answer and goroutine id extracted by runtime.Stack?

  2. Why does Go FAQ answer "They expose no unique identifier"?

I want to clearly understand "Why is there no goroutine ID?" answer!

runtime.Stack() seems to provide goroutine id. https://go.dev/play/p/5b6FD7C8S6-

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
    close(done)
}

var (
    goroutinePrefix = []byte("goroutine ")
    errBadStack     = errors.New("invalid runtime.Stack output")
)

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]))
}

And, there is another approach getting goroutine id by eBPF.

how to get goroutine id with ebpf

keisku
  • 17
  • 2
  • 4
    You are confusing the language specification with an implementation. The language does not specify an ID for a goroutines, an implementation may use one internally. – JimB May 11 '23 at 00:16
  • Thank you for your answer. Indeed, I am confused. Would you mind rephrasing "The language does not specify an ID for a goroutines, an implementation may use one internally" to another explanation? Who assigns an ID that we can get from runtime.Stack()? I am understanding that Go runtime assigns a goroutine id and expose it through runtime.Stack(). – keisku May 11 '23 at 00:38
  • 1
    One difference is: You should not use a goroutine id and that's why the language doesn't expose one but there are ugly hacks to synthesize one if you really want to shoot your foot. – Volker May 11 '23 at 05:01

2 Answers2

3

What's the difference between "unique identifier" in Go FAQ answer and goroutine id extracted by runtime.Stack?

The FAQ states that goroutines do not expose a unique identifier, name, or data structure to the programmer.

The runtime does need a way to identify a goroutine, but there is not a supported way to get that identifier.

The Go documentation does not specify the format of the stacktrace returned by runtime.Stack or the meaning of the goroutine number. The code in the question may retrieve a unique id now, but there's no guarantee that the code will do so in the future.

2

Goroutines do not have names; they are just anonymous workers. They expose no unique identifier, name, or data structure to the programmer.

Let's reinterpret this quote in a way that more clearly answer your question (in my own words):

The Go language does not provide any interface for uniquely identifying Goroutines.

Interfaces provided by the language and standard library are subject to strong policies from the Go project, mainly:

  • The interface does what it says it does
  • The interface will remain compatible with future Go 1.x versions

Therefore, we should assume that any method of identifying goroutines does not benefit from those promises. In other words, the Go project takes no responsibility for ensuring that it actually works now, or at any point in the future.

Hymns For Disco
  • 7,530
  • 2
  • 17
  • 33