Best way to pass context.Context to a closure executed in a separate goroutine

三世轮回 提交于 2021-02-10 06:00:16

问题


What is best way to pass context.Context to closure to be executed in a separate goroutine?

Since I'm not mutating context.Context inside the closure, I assume both options are valid. 2nd option can save me tiny bit of memory by not copying the interface.

1) pass as an argument

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) expose outer context variable

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:


Both should be fine. The key to remember is that contexts are immutable. This means there's no risk of a race condition where some other goroutine is updating the context as you're trying to read it, so you don't need to worry about the normal synchronization methods.

So in short, nothing special is needed so #2 is just fine. Since #1 isn't actually executing a closure, it's ideal in situations where you want to execute a named function, which takes a context argument


Note on terminology: Your original question (which I edited for clarity) asked about executing "a goroutine in a closure." Technically speaking, this is non-sense. But it's a common confusion. Goroutines are light-weight threads of execution. Functions are bits of code. They are not the same thing, so referring to functions or closures as goroutines doesn't really make sense. See this answer for more details.



来源:https://stackoverflow.com/questions/54976927/best-way-to-pass-context-context-to-a-closure-executed-in-a-separate-goroutine

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!