go - 如何使用 channel 收集各种goroutine的响应

标签 go concurrency coroutine goroutine

我是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已关闭时,它将继续运行。

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

经验丰富的Go程序员将如何使用channels解决此问题?

最佳答案

这是使用WaitGroup而不是等待固定数量的结果的解决方案。

package main

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

func process(input int, wg *sync.WaitGroup, resultChan chan<- 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)
    }

    fmt.Println(result)
}

关于go - 如何使用 channel 收集各种goroutine的响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61821424/

相关文章:

templates - Go 模板示例

go - rot13密码有什么问题?

java - 不同的不同线程修改共享列表的不同索引

python - 为什么我们需要 python 中的协程?

c++ - 安全的跨平台协程

mongodb - Go 命令返回未找到但在终端中工作

go - 并发 goroutine 尝试访问数据库时避免 SQLite 文件/数据库锁定的预防措施?

java - 如何正确管理单线程执行?

c# - 如何将 ConcurrentDictionary 包装在 BlockingCollection 中?

python - 异步操作应该用@asyncio.coroutine 装饰什么?