将 context.Context 传递给在单独的 goroutine 中执行的闭包的最佳方法

Ste*_*eve 6 closures go goroutine

context.Context传递到闭包以在单独的 goroutine 中执行的最佳方法是什么?

由于我没有context.Context在闭包内进行变异,因此我认为这两个选项都是有效的。第二个选项可以通过不复制接口来节省一点内存。

1)作为参数传递

func run(ctx context.Context) {
  for i := 0; i <= 5; i++ {
    go func(id int, ictx context.Context) {
      for {
        select {
          case <- ictx.Done():
            return
          default:
            // do something
        }
      }
    }(i, ctx)
  }
}
Run Code Online (Sandbox Code Playgroud)

2)暴露外部上下文变量

func run(ctx context.Context) {
  for i := 0; i <= 5; i++ {
    go func(id int) {
      for {
        select {
          case <- ctx.Done():
            return
          default:
            // do something
        }
      }
    }(i)
  }
}
Run Code Online (Sandbox Code Playgroud)

Fli*_*mzy 5

两者都应该没问题。要记住的关键是上下文是不可变的。这意味着当您尝试读取上下文时,其他一些 goroutine 正在更新上下文,因此不存在竞争条件的风险,因此您无需担心正常的同步方法。

简而言之,不需要什么特别的,所以#2 就可以了。由于 #1 实际上并未执行闭包,因此在您想要执行带有上下文参数的命名函数的情况下它是理想的选择


术语说明:您最初的问题(为了清楚起见,我对其进行了编辑)询问如何执行“闭包中的 goroutine”。从技术上来说,这是无意义的。但这是一个常见的困惑。Goroutine 是轻量级的执行线程。函数是一段代码。它们不是同一件事,因此将函数或闭包称为 goroutine 并没有真正的意义。有关更多详细信息,请参阅此答案。