【问题标题】:How to recover the input of multiple go routines called in a loop如何恢复循环中调用的多个 go 例程的输入
【发布时间】:2018-08-05 06:42:46
【问题描述】:

我有一个循环抛出多个 go 例程,它们调用一个函数,该函数使 http 获取请求并计算和对象。

我想恢复所有这些例程的结果。 我尝试使用频道,但嘿是空的,即使我强制等待所有例程完成。

这是启动例程的代码:

func main() {
    pairs := getPairs() //Returns an array of strings
    c := make(chan result)
    for _, product := range pairs {
        go getScore(product.Symbol, 1, c)
    }
    fmt.Println(len(c))
    time.Sleep(5000 * time.Millisecond)
    fmt.Println(len(c))
}

在 getScore() 结束时我这样做了,c 是函数中通道的名称,res 是函数的结果

c <- res

通道的长度在两个打印中都是 0。

获得函数结果的最佳方法是什么?

【问题讨论】:

    标签: go channels routines


    【解决方案1】:

    通道是针对共享内存的同步原型(从简单的角度来看)。缓冲通道具有长度但不是常规通道。缓冲通道在少量情况下很有用,但不是通用方法。

    按对或对的长度添加循环的最简单方法:

    // start processing
    for _, product := range pairs {
        go getScore(product.Symbol, 1, c)
    }
    // getting a result
    for i:=0; i<len(pairs); i ++ {
        result := <-c
        // process a result value
    }
    

    或者另一种方法是在另一个灌浆中收集结果:

    // result and sync variable
    var (
       wait sync.WaitGroup
       result int32
    ) 
    // start processing
    for _, product := range pairs {
        wait.Add(1)
        go getScore(product.Symbol, 1, c)
        go func() {
            defer wait.Done()
            // simple accumulate or maybe more complicated actions
            atomic.AddInt32(&result, <-c)
        }()
    }
    // wait finishing
    wait.Wait()
    

    【讨论】:

      【解决方案2】:
      c := make(chan result)
      

      创建一个无缓冲的通道。因此发送语句,例如

      c <- res
      

      在另一个 goroutine 尝试接收操作之前无法继续。

      换句话说,在你的主 goroutine 中执行接收操作的数量与将要从其他 goroutine 尝试发送的数量相匹配。像这样:

      for _, product := range pairs {
          go getScore(product.Symbol, 1, c)
      }
      for x := 0; x < len(pairs); x++ {
          fmt.Println(<-c)
      }
      

      请参阅the Go Tour section on channelsthe Effective Go section on channels 了解更多信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-10-23
        • 1970-01-01
        • 2013-05-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多