亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

將來自多個 go routines 的響應獲取到一個數組中

將來自多個 go routines 的響應獲取到一個數組中

Go
眼眸繁星 2023-06-05 17:18:28
我需要從多個 go 例程中獲取響應并將它們放入一個數組中。我知道通道可用于此目的,但我不確定如何確保所有 go 例程都已完成結果處理。因此我正在使用等待組。代碼func main() {  log.Info("Collecting ints")  var results []int32  for _, broker := range e.BrokersByBrokerID {      wg.Add(1)      go getInt32(&wg)  }  wg.Wait()  log.info("Collected")}func getInt32(wg *sync.WaitGroup) (int32, error) {  defer wg.Done()  // Just to show that this method may just return an error and no int32  err := broker.Open(config)  if err != nil && err != sarama.ErrAlreadyConnected {    return 0, fmt.Errorf("Cannot connect to broker '%v': %s", broker.ID(), err)  }  defer broker.Close()  return 1003, nil}我的問題如何將所有響應 int32(可能返回錯誤)放入我的 int32 數組,確保所有 go 例程都已完成處理工作并返回錯誤或 int?
查看完整描述

4 回答

?
繁花如伊

TA貢獻2012條經驗 獲得超12個贊

如果您不處理作為 goroutine 啟動的函數的返回值,它們將被丟棄。

您可以使用切片來收集結果,其中每個 goroutine 都可以接收將結果放入的索引,或者元素的地址。請注意,如果您使用它,則必須預先分配切片,并且只能寫入屬于 goroutine 的元素,您不能“觸摸”其他元素,也不能附加到切片。

或者您可以使用一個通道,goroutines 在該通道上發送包含它們處理的項目的索引或 ID 的值,以便收集 goroutine 可以識別或排序它們。

請注意,這里不需要等待組,因為我們知道我們期望通道上的值與我們啟動的 goroutine 一樣多。

type result struct {

? ? task int32

? ? data int32

? ? err? error

}


func main() {

? ? tasks := []int32{1, 2, 3, 4}


? ? ch := make(chan result)


? ? for _, task := range tasks {

? ? ? ? go calcTask(task, ch)

? ? }


? ? // Collect results:

? ? results := make([]result, len(tasks))


? ? for i := range results {

? ? ? ? results[i] = <-ch

? ? }


? ? fmt.Printf("Results: %+v\n", results)

}


func calcTask(task int32, ch chan<- result) {

? ? if task > 2 {

? ? ? ? // Simulate failure

? ? ? ? ch <- result{task: task, err: fmt.Errorf("task %v failed", task)}

? ? ? ? return

? ? }


? ? // Simulate success

? ? ch <- result{task: task, data: task * 2, err: nil}

}

輸出(在Go Playground上嘗試):


Results: [{task:4 data:0 err:0x40e130} {task:1 data:2 err:<nil>} {task:2 data:4 err:<nil>} {task:3 data:0 err:0x40e138}]



查看完整回答
反對 回復 2023-06-05
?
楊__羊羊

TA貢獻1943條經驗 獲得超7個贊

我也相信你必須使用頻道,它必須是這樣的:


package main


import (

    "fmt"

    "log"

    "sync"

)


var (

    BrokersByBrokerID = []int32{1, 2, 3}

)


type result struct {

    data string

    err string // you must use error type here

}


func main()  {

    var wg sync.WaitGroup

    var results []result

    ch := make(chan result)


    for _, broker := range BrokersByBrokerID {

        wg.Add(1)

        go getInt32(ch, &wg, broker)

    }


    go func() {

        for v := range ch {

            results = append(results, v)

        }

    }()


    wg.Wait()

    close(ch)


    log.Printf("collected %v", results)

}


func getInt32(ch chan result, wg *sync.WaitGroup, broker int32) {

    defer wg.Done()


    if broker == 1 {

        ch <- result{err: fmt.Sprintf("error: gor broker 1")}

        return

    }


    ch <- result{data: fmt.Sprintf("broker %d - ok", broker)}

}

結果將如下所示:


2019/02/05 15:26:28 collected [{broker 3 - ok } {broker 2 - ok } { error: gor broker 1}]



查看完整回答
反對 回復 2023-06-05
?
拉莫斯之舞

TA貢獻1820條經驗 獲得超10個贊

package main


import (

    "fmt"

    "log"

    "sync"

)


var (

    BrokersByBrokerID = []int{1, 2, 3, 4}

)


type result struct {

    data string

    err  string // you must use error type here

}


func main() {

    var wg sync.WaitGroup

    var results []int

    ch := make(chan int)

    done := make(chan bool)

    for _, broker := range BrokersByBrokerID {

        wg.Add(1)


        go func(i int) {

            defer wg.Done()

            ch <- i

            if i == 4 {

                done <- true

            }


        }(broker)

    }

L:

    for {

        select {

        case v := <-ch:


            results = append(results, v)

            if len(results) == 4 {

                //<-done

                close(ch)

                break L

                

            }


        case _ = <-done:

            break

        }

    }


    fmt.Println("STOPPED")

    //<-done

    wg.Wait()


    log.Printf("collected %v", results)


}


查看完整回答
反對 回復 2023-06-05
?
月關寶盒

TA貢獻1772條經驗 獲得超5個贊

package main


import (

    "fmt"

    "log"

    "sync"

    "time"

)


var (

    BrokersByBrokerID = []int{1, 2, 3, 4}

)


type result struct {

    data string

    err  string // you must use error type here

}


func main() {    

    var wg sync.WaitGroup.   

    var results []int  

    ch := make(chan int)  

    done := make(chan bool) 

    for _, broker := range BrokersByBrokerID {                      

       wg.Add(1)


        go func(i int) {

            defer wg.Done()

            ch <- i

            if i == 4 {

                done <- true

            } 


        }(broker)

    }

    

    for v := range ch {


        results = append(results, v)

        if len(results) == 4 {

            close(ch)

        }


    }


    fmt.Println("STOPPED")

    <-done

    wg.Wait()

    

    log.Printf("collected %v", results)



}



</pre>


查看完整回答
反對 回復 2023-06-05
  • 4 回答
  • 0 關注
  • 230 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號