我有一个递归函数。该函数将根据它获得的数据使用各种不同的值调用自身,因此递归的数量和深度是未知的:每次调用可能会调用自己零次或多次。该函数可以返回任意数量的值。我想通过让 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阅读所有的结果。
- 1 回答
- 0 关注
- 199 浏览
添加回答
举报
0/150
提交
取消