功能说明
示例用 container/heap 维护按优先级排序的任务队列,再交给固定数量的工作 goroutine 消费。jobQueue.Less 先比较 Priority,高优先级排在前面;优先级相同时按 ID 升序,保证同一优先级的任务先进先出。调度 goroutine 从堆中弹出任务写入通道,工作协程把结果写回另一个通道,主协程收集全部结果。
关键代码
func (q jobQueue) Less(i, j int) bool {
if q[i].Priority != q[j].Priority {
return q[i].Priority > q[j].Priority
}
return q[i].ID < q[j].ID
}
...
jobCh <- heap.Pop(&queue).(Job)
heap.Init 必须在弹出前调用,否则切片不满足堆性质;Push 与 Pop 使用指针接收者,才能修改底层切片。
使用注意
- 多工作协程并发消费时,结果顺序取决于完成顺序,不保证与优先级一致;优先级只决定派发顺序。
- 上下文取消后,调度器和工作者都会退出,已经派发的任务可能只完成一部分。
- 结果通道容量有限,收集方必须持续读取,否则工作者会阻塞。
workers小于 1 会直接返回错误,避免创建无法推进的池。- 生产环境可以给任务增加超时与重试,并在关闭时等待所有工作者退出。
验证方式
运行示例应看到 4 条结果,auth 与 search 都使用大写输出;由于只有两个工作者,完成顺序可能变化。把 workers 改为 1 可以观察派发顺序,把上下文超时改为纳秒可验证取消路径。