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

时间:2019-03-04 05:04:35

标签: go closures 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)
  }
}

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

1 个答案:

答案 0 :(得分:2)

两个都很好。要记住的关键是上下文是不可变的。这意味着在您尝试读取上下文时,其他goroutine会在更新上下文的情况下不会出现竞争状况的风险,因此您无需担心正常的同步方法。

因此,简而言之,不需要特殊设置,因此#2很好。由于#1实际上并没有执行闭包,因此在要执行带有上下文参数的命名函数的情况下,它是理想的选择


有关术语的说明:您最初的问题(为清晰起见,我对其进行了编辑)询问如何执行“闭包中的goroutine”。从技术上来讲,这是无稽之谈。但这是一个普遍的困惑。 Goroutines是轻量级的执行线程。函数是代码的一部分。它们不是一回事,因此将函数或闭包称为goroutines并没有任何意义。有关更多详细信息,请参见this answer