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

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

goroutine 等待頻道的響應并繼續

goroutine 等待頻道的響應并繼續

Go
30秒到達戰場 2022-06-01 16:49:26
我正在學習并發,我想實現一個簡單的示例,該示例從矩陣中獲取行并將值的數組(切片)添加到每一行。由于我使用的是通道,因此我嘗試等待每一行從 goroutine 獲得相應的結果。但是,這并不比僅同步執行此操作更好。如何讓每一行等待它們各自的結果并允許其他行同時計算它們的結果?https://play.golang.org/p/uCOGwOBeIQLpackage mainimport "fmt"/*Array:0 1 2 3 4 5 6 7 8 9+Matrix:1 0 0 0 0 0 0 0 0 00 1 0 0 0 0 0 0 0 00 0 1 0 0 0 0 0 0 00 0 0 1 0 0 0 0 0 00 0 0 0 1 0 0 0 0 00 0 0 0 0 1 0 0 0 00 0 0 0 0 0 1 0 0 00 0 0 0 0 0 0 1 0 00 0 0 0 0 0 0 0 1 00 0 0 0 0 0 0 0 0 1-> Expected result:1 1 2 3 4 5 6 7 8 90 2 2 3 4 5 6 7 8 90 1 3 3 4 5 6 7 8 90 1 2 4 4 5 6 7 8 90 1 2 3 5 5 6 7 8 90 1 2 3 4 6 6 7 8 90 1 2 3 4 5 7 7 8 90 1 2 3 4 5 6 8 8 90 1 2 3 4 5 6 7 9 90 1 2 3 4 5 6 7 8 10*/func main() {    numbers := []int {0,1,2,3,4,5,6,7,8,9}    matrix := [][]int{        {1,0,0,0,0,0,0,0,0,0},        {0,1,0,0,0,0,0,0,0,0},        {0,0,1,0,0,0,0,0,0,0},        {0,0,0,1,0,0,0,0,0,0},        {0,0,0,0,1,0,0,0,0,0},        {0,0,0,0,0,1,0,0,0,0},        {0,0,0,0,0,0,1,0,0,0},        {0,0,0,0,0,0,0,1,0,0},        {0,0,0,0,0,0,0,0,1,0},        {0,0,0,0,0,0,0,0,0,1},    }    rmatrix := make([][]int, 10)    for i, row := range matrix {        cResult := make(chan []int)        go func(row []int, numbers []int, c chan <- []int) {            c <- addRow(row,numbers)        }(row,numbers,cResult)        //this read from the channel will block until the goroutine sends its result over the channel        rmatrix[i] = <- cResult    }    fmt.Println(rmatrix)}func addRow(row []int, numbers []int) []int{    result := make([]int, len(row))    for i,e := range row {        result[i] = e + numbers[i];    }    return result}
查看完整描述

3 回答

?
Helenr

TA貢獻1780條經驗 獲得超4個贊

我需要使用 async.WaitGroup并直接分配調用的結果(以保證它們返回到索引行)。謝謝@彼得


package main


import (

    "fmt"

    "sync"

)


func main() {

    numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}


    matrix := [][]int{

        {1, 0, 0, 0, 0, 0, 0, 0, 0, 0},

        {0, 1, 0, 0, 0, 0, 0, 0, 0, 0},

        {0, 0, 1, 0, 0, 0, 0, 0, 0, 0},

        {0, 0, 0, 1, 0, 0, 0, 0, 0, 0},

        {0, 0, 0, 0, 1, 0, 0, 0, 0, 0},

        {0, 0, 0, 0, 0, 1, 0, 0, 0, 0},

        {0, 0, 0, 0, 0, 0, 1, 0, 0, 0},

        {0, 0, 0, 0, 0, 0, 0, 1, 0, 0},

        {0, 0, 0, 0, 0, 0, 0, 0, 1, 0},

        {0, 0, 0, 0, 0, 0, 0, 0, 0, 1},

    }


    rmatrix := make([][]int, 10)

    var waitGroup sync.WaitGroup


    for i, row := range matrix {

        waitGroup.Add(1)

        go func(i int, row []int) {

            rmatrix[i] = addRow(row, numbers)

            waitGroup.Done()

        }(i, row)

    }

    waitGroup.Wait()

    fmt.Println(rmatrix)

}


func addRow(row []int, numbers []int) []int {

    result := make([]int, len(row))

    for i, e := range row {

        result[i] = e + numbers[i]

    }

    return result

}


查看完整回答
反對 回復 2022-06-01
?
慕容3067478

TA貢獻1773條經驗 獲得超3個贊

這個例子產生了較少數量的 goroutine,并且也保證了正確的順序,不管哪個 goroutine 先完成了它的處理。


package main


import (

    "fmt"

    "sync"

)


type rowRes struct {

    index  int

    result *[]int

}


func addRow(index int, row []int, numbers []int) rowRes {

    result := make([]int, len(row))

    for i, e := range row {

        result[i] = e + numbers[i]

    }

    return rowRes{

        index:  index,

        result: &result,

    }

}


func main() {

    numbers := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}


    matrix := [][]int{

        {1, 0, 0, 0, 0, 0, 0, 0, 0, 0},

        {0, 1, 0, 0, 0, 0, 0, 0, 0, 0},

        {0, 0, 1, 0, 0, 0, 0, 0, 0, 0},

        {0, 0, 0, 1, 0, 0, 0, 0, 0, 0},

        {0, 0, 0, 0, 1, 0, 0, 0, 0, 0},

        {0, 0, 0, 0, 0, 1, 0, 0, 0, 0},

        {0, 0, 0, 0, 0, 0, 1, 0, 0, 0},

        {0, 0, 0, 0, 0, 0, 0, 1, 0, 0},

        {0, 0, 0, 0, 0, 0, 0, 0, 1, 0},

        {0, 0, 0, 0, 0, 0, 0, 0, 0, 1},

    }

    rmatrix := make([][]int, 10)


    // Buffered channel

    rowChan := make(chan rowRes, 10)


    wg := sync.WaitGroup{}


    // Reciever goroutine

    go recv(rowChan, rmatrix)


    for i := range matrix {

        wg.Add(1)

        go func(index int, row []int, w *sync.WaitGroup) {

            rowChan <- addRow(index, row, numbers)

            w.Done()

        }(i, matrix[i], &wg)

    }

    wg.Wait()

    close(rowChan)

    fmt.Println(rmatrix)

}


func recv(res chan rowRes, rmatrix [][]int) {

    for {

        select {

        case k, ok := <-res:

            if !ok {

                return

            }

            rmatrix[k.index] = *k.result

        }

    }

}



查看完整回答
反對 回復 2022-06-01
?
楊魅力

TA貢獻1811條經驗 獲得超6個贊

流水線法



taskChannel := make(chan string,1000); // Set up the task queue

wg := sync.WaitGroup


// Task release

wg.add(1)

go func(&wg,taskChannel) {

      defer wg.Down()

      for i in "task list" {

        taskChannel <- "Stuff the characters you want to deal with here"

      }


    // After the task is sent and closed

    close(taskChannel)

}(wg *sync.WaitGroup,taskChannel chan string)


// Task execution

go func(&wg,taskChannel,1000) {

    defer wg.Down()

    limit := make(chan bool,limitNumber); // Limit the number of concurrent

    tg := sync.WaitGroup

    loop:

    for {

      select {

      case task,over := <-taskChannel:

            if !over {  // If there are no more tasks, quit

                tg.Wait()  // Wait for all tasks to end

                break loop

            }


            tg.Add(1)

            limit<-true

            go func(&tg,limitm) {

                defer func() {

                    <-limit

                    tg.Down()

                }

                // Business processing logic, processing tasks

            }(tg *sync.WaitGroup,limit chan bool,task string)

      }

    }

}(wg *sync.WaitGroup,taskChannel chan string,limitNumber int)


wg.Wait()

希望能幫到你


查看完整回答
反對 回復 2022-06-01
  • 3 回答
  • 0 關注
  • 126 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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