如何关闭多个goroutine正在发送的频道?

如何关闭多个goroutine正在发送的频道?,go,channels,Go,Channels,我正在尝试并行地进行一些计算。该程序的设计使得每个工作程序goroutine将已解决难题的“片段”发送回控制器goroutine,控制器goroutine等待接收并组装从工作程序发送的所有内容 关闭单通道的idomatic目标是什么?我不能在每个goroutine中调用close,因为这样我就可以在一个封闭的频道上发送。同样,也没有办法预先确定哪一个goroutine将首先完成。这里需要sync.WaitGroup吗?是的,这是sync.WaitGroup的完美用例 您的另一个选项是每个goro

我正在尝试并行地进行一些计算。该程序的设计使得每个工作程序goroutine将已解决难题的“片段”发送回控制器goroutine,控制器goroutine等待接收并组装从工作程序发送的所有内容


关闭单通道的idomatic目标是什么?我不能在每个goroutine中调用close,因为这样我就可以在一个封闭的频道上发送。同样,也没有办法预先确定哪一个goroutine将首先完成。这里需要sync.WaitGroup吗?

是的,这是sync.WaitGroup的完美用例


您的另一个选项是每个goroutine使用1个通道,以及一个多路复用器goroutine,该goroutine从每个通道馈送到单个通道。但是这会很快变得很难处理,所以我只选择sync.WaitGroup。

下面是一个使用
sync.WaitGroup
来完成您想要的任务的示例

本例接受一个长整型列表,然后通过向N个并行工作者传递一个大小相等的输入数据块,将所有整数相加。它可以在以下设备上运行:

主程序包
进口(
“fmt”
“同步”
)
常数工作计数=10
func main(){
//一些要操作的输入数据。
//每个工人都有同等份额的工作。
数据:=制造([]整数,工作计数*10)
对于i:=范围数据{
数据[i]=i
}
//对所有条目求和。
结果:=总和(数据)
fmt.Printf(“总和:%d\n”,结果)
}
//sum通过委托操作将给定列表中的数字相加
//在输入数据的子切片上并行操作的工人。
func sum(数据[]int)int{
变量和整数
结果:=make(chan int)
延迟关闭(结果)
//从工人那里积累结果。
go func(){
为了{
挑选{

case value:=其中一些代码有点…奇怪。特别是,带有for/single case select的goroutine在不同步的情况下累积结果并覆盖变量。一些小的重新排列和事情变得更可靠/更容易理解:
package main

import (
    "fmt"
    "sync"
)

const WorkerCount = 10

func main() {
    // Some input data to operate on.
    // Each worker gets an equal share to work on.
    data := make([]int, WorkerCount*10)

    for i := range data {
        data[i] = i
    }

    // Sum all the entries.
    result := sum(data)

    fmt.Printf("Sum: %d\n", result)
}

// sum adds up the numbers in the given list, by having the operation delegated
// to workers operating in parallel on sub-slices of the input data.
func sum(data []int) int {
    var sum int

    result := make(chan int)
    defer close(result)

    // Accumulate results from workers.
    go func() {
        for {
            select {
            case value := <-result:
                sum += value
            }
        }
    }()

    // The WaitGroup will track completion of all our workers.
    wg := new(sync.WaitGroup)
    wg.Add(WorkerCount)

    // Divide the work up over the number of workers.
    chunkSize := len(data) / WorkerCount

    // Spawn workers.
    for i := 0; i < WorkerCount; i++ {
        go func(i int) {
            offset := i * chunkSize

            worker(result, data[offset:offset+chunkSize])
            wg.Done()
        }(i)
    }

    // Wait for all workers to finish, before returning the result.
    wg.Wait()

    return sum
}

// worker sums up the numbers in the given list.
func worker(result chan int, data []int) {
    var sum int

    for _, v := range data {
        sum += v
    }

    result <- sum
}