如何阻止(和加入)由未知数量的 goroutine 提供的通道?

我有一个递归函数。该函数将根据它获得的数据使用各种不同的值调用自身,因此递归的数量和深度是未知的:每次调用可能会调用自己零次或多次。该函数可以返回任意数量的值。


我想通过让 goroutines 和通道参与进来来并行化它。每次递归都inner在自己的 goroutine中运行,并在通道上发回一个值。外部函数处理这些值。


func outer(response []int) {


  results := make([]int)

  resultsChannel := make(chan int)


  inner := func(...) {

      resultsChannel <- «some result»;


      // Recurse in a new goroutine.

      for _, recursionArgument in «some calculated data» {

          go inner(recursionArgument)

      }

  }


  go inner(«initial values»);


  for {

      result := <- resultsChannel

      results = append(results, result)


      // HELP! How do I decide when to break?

  }


  return results

}

问题在于逃避结果通道循环。由于递归的“形状”(未知的数量和深度),我不能说“在n 个事件后完成”,也不能发送哨兵值。


如何检测所有递归何时发生并从 返回outer?有没有更好的方法来解决这个问题?


慕的地6264312
浏览 200回答 1
1回答

Helenr

您可以使用 async.WaitGroup来管理您生成的 goroutine 的集合:Add(1)在生成每个新 goroutine 之前以及Done每个 goroutine 完成时调用。所以像这样:var wg sync.WaitGroupinner := func(...) {&nbsp; &nbsp; ...&nbsp; &nbsp; // Recurse in a new goroutine.&nbsp; &nbsp; for _, recursionArgument := range «some calculated data» {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; go inner(recursionArgument)&nbsp; &nbsp; }&nbsp; &nbsp; ...&nbsp; &nbsp; wg.Done()}wg.Add(1)go inner(«initial values»)现在等待wg会告诉你所有 goroutine 何时完成。如果您正在从通道读取结果,判断何时没有更多结果的明显方法是关闭通道。你可以通过另一个 goroutine 来为我们做到这一点:go func() {&nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; close(resultsChannel)}()您现在应该能够简单地range在resultsChannel阅读所有的结果。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go