登录
首页 >  Golang >  Go问答

如何等待第一个完成的 goroutine

来源:stackoverflow

时间:2024-04-09 12:51:32 471浏览 收藏

知识点掌握了,还需要不断练习才能熟练运用。下面golang学习网给大家带来一个Golang开发实战,手把手教大家学习《如何等待第一个完成的 goroutine》,在实现功能的过程中也带大家重新温习相关知识点,温故而知新,回头看看说不定又有不一样的感悟!

问题内容

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

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

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

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

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


解决方案


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

  1. 为每条数据创建一个新通道。我不确定这对性能有何影响,因此您可以对此进行一些检查。
  2. 向两种算法发送相同的输出通道。
  3. 获取来自频道的第一个值,看看您是否喜欢它。
  4. 如果不这样做,请采用第二个值。
  5. 继续,无需担心开放通道。 We have garbage collection in 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)
    }
}

您可以使用 buffer channel 来实现这一点,简单的代码是:

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
        }
    }
}

今天带大家了解了的相关知识,希望对你有所帮助;关于Golang的技术知识我们会一点点深入介绍,欢迎大家关注golang学习网公众号,一起学习编程~

声明:本文转载于:stackoverflow 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>