Go中生产者-消费者模型核心是channel+goroutine:channel作线程安全队列,无缓冲实现同步,有缓冲解耦速度差异;生产者close后消费者range自动退出;可用WaitGroup协调生命周期,并扩展错误处理、限流与context超时控制。

用 Go 实现生产者-消费者模型,核心是靠 channel + goroutine,而不是锁或条件变量。它天然适合这个场景,简洁、安全、不易出错。
用 channel 做共享队列
channel 本身就是线程安全的队列,不需要额外加锁。生产者往 channel 写,消费者从 channel 读,Go 运行时自动处理同步和阻塞。
- 无缓冲 channel:生产者和消费者必须同时就绪才能通信(严格同步)
- 有缓冲 channel:如
ch := make(chan int, 10),可暂存 10 个任务,解耦生产与消费速度差异 - 关闭 channel 表示“不再生产”,消费者可用
for v := range ch安全退出
启动多个 goroutine 并发执行
生产者和消费者都用 go func() {}() 启动,数量按需设置。例如:
- 1 个生产者 goroutine 持续生成任务(如读文件、收网络请求)
- 3 个消费者 goroutine 并行处理任务(如计算、写数据库)
- 所有 goroutine 共享同一个 channel,无需手动协调
控制生命周期与优雅退出
避免 goroutine 泄漏的关键是明确谁负责关闭 channel,并通知所有消费者结束。
立即学习“go语言免费学习笔记(深入)”;
- 通常由生产者在完成所有任务后调用
close(ch) - 消费者用
for job := range ch自动退出,不需轮询或标志位 - 若需等待所有消费者完成,用
sync.WaitGroup计数
加一层抽象:带错误处理和限流的版本
真实项目中常需扩展,比如:
- 任务带返回结果或错误,用结构体封装:
type Task struct { Input int; Err error } - 限制并发消费者数,用带缓冲的 channel 控制“令牌”(类似 semaphore)
- 加 context.Context 支持超时或取消,比如
select { case ch
基本上就这些。Go 的并发模型不是模拟传统多线程,而是用 channel 明确数据流动,让生产者消费者各司其职,写起来顺,跑起来稳。










