How to identify a goroutine?

Solution 1:

A workaround is possible, and involves a small piece of C code.

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

Build and run

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

Solution 2:

Play

This method is simpler than @Alex B. It use the fact that debug.Stack() return stack trace in the form of byte slice which contains goroutine its id in the second word boundary along with, well stack trace. And parse it.

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