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

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


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")

}


一只名叫tom的猫
浏览 179回答 2
2回答

繁华开满天机

没有任何问题......它有效。但是,关闭通道确实应该是生产者的工作(而不是消费者)。为此..我建议您将整个生产者进程移动到一个goroutine中并等待..然后关闭通道:package mainimport "fmt"import "sync"func main() {&nbsp; &nbsp; ch := make(chan int, 3)&nbsp; &nbsp; var wg sync.WaitGroup&nbsp; &nbsp; go func() {&nbsp; &nbsp; &nbsp; &nbsp; for i := 0; i < 3; i++ {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; wg.Add(1)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; go func(i int) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defer wg.Done()&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ch <- i&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }(i)&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; wg.Wait()&nbsp; &nbsp; &nbsp; &nbsp; close(ch) // producer is now closing the channel&nbsp; &nbsp; }()&nbsp; &nbsp; // Consumer has the single responsibility of iterating over the channel&nbsp; &nbsp; for v := range ch {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Println("consume ", v)&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Printf("All done")}See it in the Go Playground

开满天机

我相信你的例子是人为的,但你的例子可以变得更简单:ch := make(chan int, 99)for i := 0; i < 3; i++ {&nbsp; &nbsp; go func(i int) {&nbsp; &nbsp; &nbsp; &nbsp; ch <- i&nbsp; &nbsp; }(i)}for i := 0; i < 3; i++ {&nbsp; &nbsp; v := <- ch&nbsp; &nbsp; fmt.Println("consume ", v)}fmt.Println("All done")您的实际代码可能更复杂,并且需要诸如 waitGroup 之类的东西,如果是这种情况,请尽您所能来解释您的具体问题。关闭一个范围内的通道以退出该范围似乎是不惯用的围棋。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go