如何使用渠道收集各种goroutine的响应

问题描述 投票:1回答:2

我是Golang的新手,我有一个使用WaitGroupMutex实现的任务,我想将其转换为使用Channels

对任务的非常简短的描述是:拒绝处理所需结果的go例程,并在main go例程中等待并收集所有结果。

我使用WaitGroupMutex的实现如下:

package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

func process(input int, wg *sync.WaitGroup, result *[]int, lock *sync.Mutex) *[]int {
    defer wg.Done()
    defer lock.Unlock()

    rand.Seed(time.Now().UnixNano())
    n := rand.Intn(5)
    time.Sleep(time.Duration(n) * time.Second)
    lock.Lock()
    *result = append(*result, input * 10)

    return result
}

func main() {

    var wg sync.WaitGroup
    var result []int
    var lock sync.Mutex
    for i := range []int{1,2,3,4,5} {
        wg.Add(1)
        go process(i, &wg, &result, &lock)
    }
}

如何使用Mutex将内存同步替换为使用Channels的内存同步?

我的主要问题是我不确定如何确定正在处理最终任务的最终执行例程,因此是否有一个例程可以关闭channel。这个想法是,通过关闭channel,主go例程可以在channel上循环,检索结果,并在看到channel已关闭时继续前进。

也可能是在这种情况下关闭渠道的方法是错误的,因此我在这里问为什么。

更有经验的程序员将如何使用channels解决此问题?

go concurrency coroutine goroutine
2个回答
1
投票

我更改了您的代码以使用该渠道。还有许多其他使用渠道的方法。

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func process(input int, out chan<- int) {
    rand.Seed(time.Now().UnixNano())
    n := rand.Intn(5)
    time.Sleep(time.Duration(n) * time.Second)
    out <- input * 10
}

func main() {
    var result []int
    resultChan := make(chan int)
    items := []int{1, 2, 3, 4, 5}

    for _, v := range items {
        go process(v, resultChan)
    }

    for i := 0; i < len(items); i++ {
        res, _ := <-resultChan
        fmt.Println("h", res)
        result = append(result, res)
    }

    close(resultChan)
    fmt.Println(result)
}

0
投票
package main

import (
    "fmt"
    "math/rand"
    "sync"
    "time"
)

func process(input int, wg *sync.WaitGroup, resultChan chan<- int) *[]int {
    defer wg.Done()

    rand.Seed(time.Now().UnixNano())
    n := rand.Intn(5)
    time.Sleep(time.Duration(n) * time.Second)

    resultChan <- input * 10
}

func main() {
    var wg sync.WaitGroup

    resultChan := make(chan int)

    for i := range []int{1,2,3,4,5} {
        wg.Add(1)
        go process(i, &wg, resultChan)
    }

    go func() {
        wg.Wait()
        close(resultChan)
    }()

    var result []int
    for r := range resultChan {
        result = append(result, r)
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.