There is no explicit function for setting or retrieving Goroutine-local storage (TLS) using runtime.SetTLS()
and runtime.GetTLS()
in Go.
The SetTLS()
and GetTLS()
functions do not exist in the Go runtime
package. However, you can achieve similar functionality using a combination of the sync.Map
type from the sync
package, and the Goroutine ID.
Here's an example:
package main
import (
"fmt"
"runtime"
"sync"
)
var tlsMap sync.Map
func setTLS(value interface{}) {
tlsMap.Store(getGID(), value)
}
func getTLS() interface{} {
value, _ := tlsMap.Load(getGID())
return value
}
func getGID() int64 {
b := make([]byte, 64)
b = b[:runtime.Stack(b, false)]
var gid uintptr
fmt.Sscanf(string(b), "goroutine %v", &gid)
return int64(gid)
}
func main() {
wg := sync.WaitGroup{}
for i := 0; i < 10; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
setTLS(id) // Set some value in TLS
fmt.Printf("Goroutine %v - TLS: %v\n", id, getTLS())
}(i)
}
wg.Wait()
}
In this example, we use a sync.Map
to store the Goroutine-local values indexed by the Goroutine ID. The setTLS()
function sets a value in the map, and getTLS()
retrieves the value from the map corresponding to the current Goroutine ID.
The getGID()
function extracts the Goroutine ID from the Goroutine stack using runtime.Stack()
and parsing the output. It works by calling runtime.Stack()
with the all
argument set to false
, which returns only the active Goroutine's stack trace. Then, it extracts the Goroutine ID from the stack trace using a simple string parsing approach.
Please note that this approach is not officially supported or recommended by the Go standard library. Goroutine-local storage is intentionally not provided by the runtime
package to encourage explicit passing of values between Goroutines using function arguments and return values or using channels.