为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕的地6264312 2021-06-30 17:15:54
我有一个递归函数。该函数将根据它获得的数据使用各种不同的值调用自身,因此递归的数量和深度是未知的:每次调用可能会调用自己零次或多次。该函数可以返回任意数量的值。我想通过让 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?有没有更好的方法来解决这个问题?
查看完整描述

1 回答

?
Helenr

TA贡献1780条经验 获得超4个赞

您可以使用 async.WaitGroup来管理您生成的 goroutine 的集合:Add(1)在生成每个新 goroutine 之前以及Done每个 goroutine 完成时调用。所以像这样:


var wg sync.WaitGroup

inner := func(...) {

    ...

    // Recurse in a new goroutine.

    for _, recursionArgument := range «some calculated data» {

          wg.Add(1)

          go inner(recursionArgument)

    }

    ...

    wg.Done()

}

wg.Add(1)

go inner(«initial values»)

现在等待wg会告诉你所有 goroutine 何时完成。


如果您正在从通道读取结果,判断何时没有更多结果的明显方法是关闭通道。你可以通过另一个 goroutine 来为我们做到这一点:


go func() {

    wg.Wait()

    close(resultsChannel)

}()

您现在应该能够简单地range在resultsChannel阅读所有的结果。


查看完整回答
反对 回复 2021-07-12
  • 1 回答
  • 0 关注
  • 199 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信