正确做法是生产者完成所有发送后关闭channel,消费者用for range安全接收;多生产者时改用WaitGroup+done channel;任务队列需缓冲和超时机制防卡死。

用 chan 实现基础生产者消费者,别直接关 channel
Go 里最自然的实现就是靠 chan,但新手常在关闭 channel 上栽跟头。比如生产者 goroutine 写完就 close(ch),消费者却还在读 —— 立刻 panic:panic: send on closed channel 或 invalid memory address(取决于读写时序)。正确做法是只由生产者决定“不发了”,消费者用 for range ch 安全接收,它会在 channel 关闭且缓冲区清空后自动退出。
关键点:
- 生产者负责
close(ch),且必须确保所有发送完成后再关(不能边发边关) - 消费者统一用
for v := range ch,不用for { select { ... }}加手动判断 - 如果多个生产者,别随便 close —— 改用
sync.WaitGroup+donechannel 协调
带缓冲和超时的 task queue,select 配 default 很关键
真实任务队列不能卡死,比如消费者处理慢、生产者突发大量任务时,得有背压控制。用带缓冲的 chan(如 make(chan Task, 100))能缓解,但缓冲满后 ch 会阻塞。这时候要用 select 配 default 做非阻塞写入,再配合超时 fallback:
default
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











