go - 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()
}
解决方案
在中间阶段,每个 goroutine 都在关闭共享输出通道,所以当第一个 goroutine 关闭它时,所有其他尝试写入它的 goroutine 都会失败。
当所有中期工作人员完成时关闭它。为此使用单独的等待组。
推荐阅读
- azure-iot-hub - iOS 14 无法识别的选择器发送到 IoTHubClient_LL_DoWork() 上的实例异常
- php - 尽管该行是时间戳,但 SQL 声称日期时间值不正确
- java - 接口初始化不初始化超接口
- javascript - HTTP/HTTPS 响应方法
- json - 尝试从服务器获取 JSON,但我不断收到错误消息,说它无效
- ruby-on-rails - docker-compose 不会打开 /bin/bash
- selenium - 无头 chrome 中的元素属性与常规 chrome 不同,因此 selenium 返回 NoSuchElementException
- java - Spring boot @RedisHash 创建多个键而不是一个
- angular - 由于 Private 成员,Angular AOT 构建失败
- python - 无法使用 python 抓取“链接文本”