【问题标题】:Closing and ranging over go channels关闭和测距 go 通道
【发布时间】:2021-06-24 03:46:57
【问题描述】:

我是 Go 新手,我也很难阅读文档。任何人都可以帮助解释下面的代码有什么问题

package main

import (
    "fmt"
)

func main() {
    c := make(chan int)

    for i := 0; i < 10; i++ {
        go func() {
            add(c)
        }()
    }
    close(c)

    for v := range c {
        fmt.Println(v)
    }
}

func add(c chan<- int) {
    c<-123
}

【问题讨论】:

  • 它会因为 write on closed channel 错误而恐慌。
  • 您无法在关闭的频道上发送。您关闭通道并在通道上发送不同步。您应该只在所有发送完成后关闭通道。为此,请使用sync.WaitGroup
  • 我修改了你的代码以人为地演示恐慌play.golang.org/p/v7bF-01t6sf它没有出现在你的原始代码中,因为main会在123添加到c之前退出。
  • @GeneKoh 显然,因为您只想在所有发送完成后从通道接收,但是在有人在无缓冲通道上从它接收之前,发送无法继续。使用并发消费者,例如:play.golang.org/p/BMtXkmtQxlx

标签: go


【解决方案1】:

根据 icza 的建议:

package main

import (
    "fmt"
    "sync"
)

func main() {
    c := make(chan int)

    var wgConsumer sync.WaitGroup
    wgConsumer.Add(1)
    go func() {
        defer wgConsumer.Done()
        for v := range c {
            fmt.Println(v)
        }

    }()

    var wg sync.WaitGroup
    wg.Add(10)

    for i := 0; i < 10; i++ {
        go func() {
            add(c)
            defer wg.Done()
        }()

    }
    wg.Wait()
    close(c)

    wgConsumer.Wait()

}

func add(c chan<- int) {
    c <- 123
}

输出:

123
123
123
123
123
123
123
123
123
123

【讨论】:

    猜你喜欢
    • 2016-08-09
    • 2018-04-15
    • 2011-05-26
    • 2018-05-22
    • 2021-03-14
    • 2019-01-13
    • 2015-10-02
    • 1970-01-01
    • 2018-02-18
    相关资源
    最近更新 更多