本文介绍一种基于 sync.waitgroup 和非阻塞通道操作的优雅方案,解决“工作者可动态生成新任务、且所有工作者空闲时自动退出”的并发调度问题,避免竞态、死锁与缓冲区大小依赖。
在构建爬虫、图遍历、并行任务分发等场景中,常需一个能自增长、自收敛的工作者池:初始一批任务入队,每个工作者处理任务时可能产生若干新任务,这些新任务需被及时分发;而当所有工作者均空闲、且任务队列为空时,整个系统应安全终止——既不能遗漏任务,也不能因等待而永久挂起。
Go 标准库中的 sync.WaitGroup 是管理动态任务生命周期的理想工具。它不依赖计时器或轮询,而是通过原子增减计数精准反映“当前活跃任务数”。结合非阻塞发送(select + default),我们能让工作者在无法立即入队新任务时,主动降级为“本地递归执行”,从而彻底规避通道阻塞和死锁风险。
以下是核心实现模式: