Go中用channel实现异步任务队列的核心是channel作缓冲区+goroutine池消费,支持并发控制、有序提交与执行,属轻量内存级方案;定义Task结构体、声明有缓冲chan Task、启动N个for range循环goroutine池执行任务。

在 Go 中用 channel 实现异步任务队列,核心是利用 channel 作为任务缓冲区 + goroutine 池消费任务,避免阻塞主线程、控制并发数、保证任务有序提交与执行。这不是完整的消息队列(如 Redis Queue),而是轻量、内存级、适合内部解耦和并发控制的方案。
用 channel 构建任务通道
定义一个结构体表示任务,再用 channel 传递任务实例。channel 容量可设为有缓冲,防止生产过快导致阻塞:
- 任务类型建议带执行函数和参数,支持泛化处理
- channel 声明为
chan Task,不暴露底层细节,便于后续扩展 - 缓冲大小根据预期峰值任务量设定,例如
make(chan Task, 100)
启动固定数量的工作 goroutine 池
预启动 N 个 goroutine 持续从 channel 中接收任务并执行,实现并发可控:
- 每个 goroutine 写成死循环:
for task := range taskCh { task.Run() } - 启动时用
for i := 0; i - goroutine 自动退出需配合
close(taskCh)或使用context控制生命周期
安全提交任务并支持等待完成
外部代码通过 channel 发送任务,如需等待所有任务结束,可用 sync.WaitGroup 配合:
立即学习“go语言免费学习笔记(深入)”;
- 每次发送前
wg.Add(1),任务函数末尾调用wg.Done() - 提交完所有任务后,另起 goroutine 调用
wg.Wait()避免阻塞主流程 - 若需结果,可在 Task 结构中嵌入
resultCh chan,执行完写入结果
优雅关闭与资源清理
程序退出前应停止接收新任务,并等待正在执行的任务完成:
- 关闭 channel:
close(taskCh),使所有 worker 的range循环自然退出 - 用
sync.WaitGroup等待 worker 全部退出,或用context.WithTimeout加超时保护 - 避免直接杀 goroutine;不要在 worker 内部重开 channel 或泄漏资源
不复杂但容易忽略:channel 关闭后仍可读取剩余值,但不能再写;worker 必须检查是否已关闭(task, ok := )才能安全退出。










