英文:
Does Go have something like ThreadLocal from Java?
问题
我使用Go和Gin来搭建我的网站,并想知道数据库访问时间。我使用goroutine,所以如果不使用类似线程本地存储的东西,我必须几乎改变每个函数来实现。Go有没有一个好的方法来做到这一点?
英文:
I use Go and Gin to setup my website and want to know the database access time. I use goroutine so if don't use something like thread-local, I must change almost every function to do it. Does Go have a good way to do it?
答案1
得分: 36
Go运行时和标准库没有提供goroutine本地存储或可用于实现goroutine本地存储的goroutine标识符。
第三方gls包以一种有趣的方式实现了goroutine本地存储。有些人觉得这个包很可怕,而其他人则认为它很聪明。
Go团队建议显式地将上下文作为函数参数传递,而不是使用goroutine本地存储。有关更多信息,请参阅上下文博文和包文档。
英文:
The Go runtime and standard libraries do not provide goroutine local storage or a goroutine identifier that can be used to implement goroutine local storage.
The third party gls package implements goroutine local storage in an interesting way. Some find this package horrifying and others think it's clever.
The Go team recommends passing context explicitly as function argument instead of using goroutine local storage. See the context blog post and package documentation for more information.
答案2
得分: 1
请看这个仓库 routine,随意感受。
var threadLocal = routine.NewThreadLocal()
var inheritableThreadLocal = routine.NewInheritableThreadLocal()
func main() {
threadLocal.Set("hello world")
inheritableThreadLocal.Set("Hello world2")
fmt.Println("threadLocal:", threadLocal.Get())
fmt.Println("inheritableThreadLocal:", inheritableThreadLocal.Get())
// 子协程无法读取之前分配的 "hello world"。
go func() {
fmt.Println("threadLocal in goroutine:", threadLocal.Get())
fmt.Println("inheritableThreadLocal in goroutine:", inheritableThreadLocal.Get())
}()
// 然而,可以通过 Go/GoWait/GoWaitResul 函数启动一个新的子协程,并自动传递当前协程的所有可继承变量。
routine.Go(func() {
fmt.Println("threadLocal in goroutine by Go:", threadLocal.Get())
fmt.Println("inheritableThreadLocal in goroutine by Go:", inheritableThreadLocal.Get())
})
// 等待子协程执行完毕。
time.Sleep(time.Second)
}
英文:
See this repo routine, feel your free.
var threadLocal = routine.NewThreadLocal()
var inheritableThreadLocal = routine.NewInheritableThreadLocal()
func main() {
threadLocal.Set("hello world")
inheritableThreadLocal.Set("Hello world2")
fmt.Println("threadLocal:", threadLocal.Get())
fmt.Println("inheritableThreadLocal:", inheritableThreadLocal.Get())
// The child coroutine cannot read the previously assigned "hello world".
go func() {
fmt.Println("threadLocal in goroutine:", threadLocal.Get())
fmt.Println("inheritableThreadLocal in goroutine:", inheritableThreadLocal.Get())
}()
// However, a new sub-coroutine can be started via the Go/GoWait/GoWaitResul function, and all inheritable variables of the current coroutine can be passed automatically.
routine.Go(func() {
fmt.Println("threadLocal in goroutine by Go:", threadLocal.Get())
fmt.Println("inheritableThreadLocal in goroutine by Go:", inheritableThreadLocal.Get())
})
// Wait for the sub-coroutine to finish executing.
time.Sleep(time.Second)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论