我是Golang的初学者,我想在Go中实现类似于Java中的映射诊断上下文(MDC)的东西,这是通过线程本地存储实现的.然而,我发现很难在Go Online中找到有关全局线程本地存储的信息.

I have several questions:

  • 有没有可能为围棋中的每个Goroutine创建一种全局线程本地存储来存储数据和上下文?

  • 在GO中,try 实现全局线程本地存储是否被视为反模式?

  • 是否建议在Go中实现全局线程局部存储来取代传递上下文的方式?

  • 假设在您的 Select 中,您更喜欢使用传递上下文的方法,还是try 实现线程本地存储来保存和管理上下文?

I've found some references to this, but I can't come to a conclusion to decide whether to implement it or not.

推荐答案

这里有几个问题,当你试图在围棋中模仿其他语言的功能时,通常会发生这些问题.

  • Goroutine不是线程.Goroutine没有线程那样的身份.
  • 上下文用于存储请求作用域状态和数据.它不是线程本地存储的替代品.
  • 如果您认为您需要线程本地存储,那么您可能误用了Goroutines.线程本地存储和线程池通常在线程创建成本较高时使用,因此您只需创建一次它们就可以重复使用它们.在围棋中不要这样做,除非Goroutine初始化代价很高.对于大多数情况,只需创建一个新的Goroutine并让它运行到完成即可.
  • 如果您仍然认为需要线程本地存储,请考虑闭包:
func f() {
   var i int
   go func() {
      // Here, use i as thread-local storage
   }()
}
  • 如果闭包不起作用,则传递一个用于线程本地存储的 struct
func f() {
  go func() {
     var t threadLocalData
     ...
     g(t)
     ...
  }{}
}

Go相关问答推荐

GORM没有从 struct 创建完整的表,如何修复?

链自定义GRPC客户端拦截器/DialOptions

Go SQLCMD比Windows本机版本慢吗?

CURL和Postman HTTP POST工作,但Golang请求失败,状态为400

如何在gofiber/websocket/v2中设置状态代码和原因

无法使用exec从管道中读取.Go中的命令

格式化 Azure SDK 的 golang 时间

Go-如何在递归函数中关闭通道

如何将验证器标记添加到嵌套字段

下载和合并时输出文件已损坏

为什么 net/http 不遵守超过 30 秒的超时持续时间?

Go 中的 Azure JWT 验证不起作用

由于 main.go 文件中的本地包导入导致构建 docker 容器时出错

Go:从 ssl 证书中获取 'subject/unstructeredName' 的值

从数据库中带有 imageurl 的文件夹中获取图像,并在我的浏览器中用 golang 中的 echo 显示

如何在 helm 中将字符串连接到 .AsConfig 的结果?

使用 Golang SQL 驱动程序连接到snowflake

Golang SSH客户端错误无法验证,try 的方法[无公钥],没有支持的方法

如何从 tinygo webassembly 目标返回对象

go 堆栈跟踪:在某些函数调用参数或返回值之后的问题(?)标记是什么意思?