首页 > 解决方案 > 如何等待第一个完成的 goroutine

问题描述

我有两种用于同一任务的算法,一种最适合某些情况,另一种适合其他情况。

所以我想在处理任务时同时启动两个goroutine,并且只使用第一个完成的goroutine返回的结果。

另外,在结果中,我需要知道它是由哪个算法返回的。如果我认为第一个返回的结果不正确,我想等待第二个结果。

我通过https://golang.org/pkg/sync/的文档阅读,似乎只能等待所有 goroutine 完成。

如何在 golang 中实现这个想法?

标签: gochannelgoroutine

解决方案


我认为您不需要使用sync,但我相信您可以提出一个解决方案。我认为最简单的解决方案是:

  1. 为每条数据创建一个新通道。我不确定这对性能的影响,因此您可能会对此进行一些检查。
  2. 将相同的输出通道发送到两种算法。
  3. 从频道中取出第一个值,看看你是否喜欢它。
  4. 如果不这样做,请取第二个值。
  5. 继续而不用担心开放通道。我们在 go 中有垃圾收集

像这样的东西:

type Result struct {
    Value     string
    Algorithm string
}

func (r *Result) String() string {
    return r.Value
}

func A(in string, out chan *Result) {
    out <- &Result{"A", "A"}
}

func B(in string, out chan *Result) {
    out <- &Result{"B", "B"}
}

func main() {
    data := []string{"foo", "bar", "baz"}

    for _, datum := range data {
        resultChan := make(chan *Result, 2)
        expectedResult := "B"

        go A(datum, resultChan)
        go B(datum, resultChan)

        result := <-resultChan
        if result.Value != expectedResult {
            fmt.Println("Unexpected result: ", result)
            result = <-resultChan
        }

        fmt.Println("Got result: ", result)
    }
}

推荐阅读