上下文包与完成的通道,避免goroutine泄漏

时间:2019-01-23 21:26:44

标签: go concurrency

有两种清除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()
    

每种方法的利弊是什么?我应该默认为哪一个?

我了解到,如果我想杀死一棵相互关联的goroutine的树,则应该使用上下文方法,但我们只能说我有一个简单的工作程序,它不会在内部启动其他goroutine。

1 个答案:

答案 0 :(得分:2)

  

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”。


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

现在您已经阅读了所有相关文档,您有什么问题?