Concurrency 如何退出通道范围/收集结果

Concurrency 如何退出通道范围/收集结果,concurrency,go,Concurrency,Go,我需要同时处理几个任务,然后“收集”结果。下面是我提出的代码,但我想知道这是否是正确的方法(即惯用/最佳实践),或者是否有我可能错过的错误 package main import "fmt" import "sync" func main() { // ch is the int provider. Cap is 99 but it should // really be 3 ch := make(chan int, 99) var wg sync.Wait

我需要同时处理几个任务,然后“收集”结果。下面是我提出的代码,但我想知道这是否是正确的方法(即惯用/最佳实践),或者是否有我可能错过的错误

package main

import "fmt"
import "sync"

func main() {
    // ch is the int provider. Cap is 99 but it should 
    // really be 3
    ch := make(chan int, 99)
    var wg sync.WaitGroup
    for i := 0; i < 3; i++ {
        wg.Add(1)
        go func(i int) {
            defer wg.Done()
            ch <- i
        }(i)
    }
    wg.Wait()
    for v := range ch {
        fmt.Println("consume ", v)
        if len(ch) == 0 {
            close(ch)
        }
    }
    fmt.Printf("All done")
}
主程序包
输入“fmt”
导入“同步”
func main(){
//ch是int提供程序。Cap是99,但它应该
//真的是3岁吗
ch:=制造(成龙国际,99)
var wg sync.WaitGroup
对于i:=0;i<3;i++{
工作组.添加(1)
go func(i int){
推迟工作组完成()
这没什么问题。它是有效的。但是,关闭频道(而不是消费者)确实应该是制作人的工作

为此,我建议您将整个制作过程移动到goroutine中,并等待……然后关闭频道:

package main

import "fmt"
import "sync"

func main() {
    ch := make(chan int, 3)
    var wg sync.WaitGroup

    go func() {
        for i := 0; i < 3; i++ {
            wg.Add(1)
            go func(i int) {
                defer wg.Done()
                ch <- i
            }(i)
        }
        wg.Wait()
        close(ch) // producer is now closing the channel
    }()

    // Consumer has the single responsibility of iterating over the channel
    for v := range ch {
        fmt.Println("consume ", v)
    }
    fmt.Printf("All done")
}
主程序包
输入“fmt”
导入“同步”
func main(){
ch:=制造(成交量,3)
var wg sync.WaitGroup
go func(){
对于i:=0;i<3;i++{
工作组.添加(1)
go func(i int){
推迟工作组完成()

ch我相信你的例子是人为的,但你的例子可以简单得多:

ch := make(chan int, 99)
for i := 0; i < 3; i++ {
    go func(i int) {
        ch <- i
    }(i)
}
for i := 0; i < 3; i++ {
    v := <- ch
    fmt.Println("consume ", v)
}
fmt.Println("All done")
ch:=make(chan int,99)
对于i:=0;i<3;i++{
go func(i int){

我没有看到你的片段中的“全部完成”的打印,这是一个你应该考虑的约束。@用户不知道额外的<代码> PROTLNN <代码>是一个约束,但是我还是添加了它。对…抱歉。真正的限制是值的数目通常是未知的。我已经使用<代码> 3 /代码>作为一个“随机”。似乎是正确的答案,通过我感觉代码看起来有点“复杂”由于额外的嵌套围棋例程。