首页 > 解决方案 > Golang - 带有通道和等待组的管道,发送关闭通道恐慌错误

问题描述

人们试图理解为什么下面的代码会产生一个panic: send on closed channel

该应用程序有几个阶段。生产者生成随机数并将它们发送到通道。模拟几个工人需要处理这些消息的场景,等待一秒钟,然后将它们发送到最后阶段。

func main() {
    var wg sync.WaitGroup
    numOfConcurrentWorkers := 2

    sourceCH := make(chan int)
    destCH := make(chan int)

    // source stage
    wg.Add(1)
    go func(wg *sync.WaitGroup, out chan int) {
        defer wg.Done()
        data := rand.Perm(10)
        for _, i := range data {
            out <- i
        }
        close(out)
    }(&wg, sourceCH)

    // mid stage
    wg.Add(numOfConcurrentWorkers)
    for c := 0; c < numOfConcurrentWorkers; c++ {
        go func(wg *sync.WaitGroup, in <-chan int, out chan int) {
            defer wg.Done()
            for i := range in {
                time.Sleep(1 * time.Second)
                out <- i
            }
            close(out)
        }(&wg, sourceCH, destCH)
    }

    // final stage
    wg.Add(1)
    go func(wg *sync.WaitGroup, in <-chan int) {
        defer wg.Done()
        for i := range in {
            log.Print("final ", i)
        }
    }(&wg, destCH)

    wg.Wait()
}

标签: go

解决方案


在中间阶段,每个 goroutine 都在关闭共享输出通道,所以当第一个 goroutine 关闭它时,所有其他尝试写入它的 goroutine 都会失败。

当所有中期工作人员完成时关闭它。为此使用单独的等待组。


推荐阅读