如何等待第一次完成goroutine

如何等待第一次完成goroutine,go,channel,goroutine,Go,Channel,Goroutine,对于同一个任务,我有两种算法,一种最适用于某些情况,另一种适用于某些其他情况 因此,每当处理任务时,我都希望同时启动两个goroutine,并且只使用第一个完成的goroutine返回的结果 另外,在结果中,我需要知道它是由哪个算法返回的。如果我认为第一个返回的结果不正确,我想等待第二个结果 我看完了的文件,似乎只能等待所有的goroutine完成 我如何在golang实现这个想法?我认为您不需要使用sync,尽管我相信您可以想出一个解决方案。我认为最简单的解决办法是: 为每段数据创建一个新通道

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

因此,每当处理任务时,我都希望同时启动两个goroutine,并且只使用第一个完成的goroutine返回的结果

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

我看完了的文件,似乎只能等待所有的goroutine完成


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

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

  • 为每段数据创建一个新通道。我不确定这对性能的影响,所以您可以对此进行一些检查
  • 向两种算法发送相同的输出通道
  • 取通道中的第一个值,看看您是否喜欢它
  • 如果没有,则取第二个值
  • 继续,不要担心开放的渠道 大概是这样的:

    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)
        }
    }
    
    类型结果结构{
    值字符串
    算法字符串
    }
    func(r*Result)String()字符串{
    返回r.值
    }
    func A(字符串内,字符串外*结果){
    
    out您可以使用缓冲通道来实现这一点,简单的代码是:

    package main
    
    import (
        "fmt"
    )
    type Result struct {
        Value     string
        Algorithm string
    }
    
    func DoTaskA(out chan *Result) {
        out <- &Result{"A", "A"}
    }
    
    func DoTaskB(out chan *Result) {
        out <- &Result{"B", "B"}
    }
    
    func IsGood(re *Result) bool {
        return re.Value == "B"
    }
    
    func main() {
        out := make(chan *Result, 1)
        go DoTaskA(out)
        go DoTaskB(out)
        for {
            re := <- out
            if IsGood(re) {
                fmt.Println("The chosen one is:", re.Algorithm)
                return
            }
        }
    }
    
    主程序包
    进口(
    “fmt”
    )
    类型结果结构{
    值字符串
    算法字符串
    }
    func DoTaskA(out chan*结果){
    
    我们让他们都将结果写入同一个通道,并使用一个例程读取结果。他们将按照在通道上发送的顺序进入。我推荐这篇文章。我认为里面有您需要的所有内容。缓冲通道或使用select语句,并在A和B中使用default子句。否则其中一个将永远阻止我f第一个值被视为良好。