【问题标题】:Context package vs done channel to avoid goroutine leak上下文包与完成通道以避免 goroutine 泄漏
【发布时间】:2019-06-17 13:18:54
【问题描述】:

清理 goroutine 有两种不同的方法。

  1. 使用 kill 通道表示取消,使用 done 通道表示 goroutine 已终止。

    type Worker struct {
      Done chan struct{}
      Kill chan struct{}
      Jobs chan Job
    }
    
    func (w *Worker) Run() {
      defer func() {
        w.Done <- struct{}{}
      }
      for {
        select {
        case <-w.Kill:
          return
        case j := <-w.Jobs:
          // Do some work
      }
    }
    
    go w.Run()
    w.Kill <- struct{}{}
    
  2. 使用context 取消

    type Worker struct {
      Ctx context.Context
      Cancel context.CancelFunc
      Jobs chan Job
    }
    
    func (w *Worker) Run() {
      for {
        select {
        case <-w.Ctx.Done():
          return
        case j := <-w.Jobs:
          // Do some work
      }
    }
    
    go w.Run()
    w.Cancel()
    

每种方法的优缺点是什么?我应该默认哪个?

我知道,如果我想杀死一棵相互连接的 goroutines,我应该使用上下文方法,但假设我有一个简单的 worker,它不会在内部启动其他 goroutines。

【问题讨论】:

  • 上下文方法更简单,可组合,允许取消或超时,并且是标准的。你为什么使用它?

标签: go concurrency


【解决方案1】:

Go 1.7 Release Notes

Context

Go 1.7 将 golang.org/x/net/context 包移入标准 图书馆作为上下文。这允许使用上下文进行取消, 超时,并在其他标准库中传递请求范围的数据 包,包括 net、net/http 和 os/exec,如下所述。

有关上下文的更多信息,请参阅package documentation 和 Go 博客文章“Go Concurrent Patterns: Context”。


有问题。引入了上下文包来解决它们。

既然您已经阅读了所有相关文档,那么您的问题是什么?

【讨论】:

  • 太棒了,我不确定 goroutine 取消的最新规范方法是什么,因为我认为我看到了一篇误导性的文章,并认为有些人在争论上下文不是取消的情况。通过您的回答,我认为它进一步证实了 context 应该是取消的默认首选方法。
猜你喜欢
  • 2016-07-25
  • 2018-10-12
  • 2016-03-17
  • 2018-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多