核心是用 time.Ticker 触发周期事件并为每次触发启 goroutine 并发执行;Ticker 通过 C 通道按固定间隔发送时间戳,不跳过 tick,即使任务未完成也会继续触发,从而实现并发调度。

在 Go 中实现定时任务并发执行,核心思路是用 time.Ticker 触发周期性事件,再为每次触发启动一个 goroutine 来异步处理任务。这种方式轻量、可控,且天然契合 Go 的并发模型。
用 Ticker 控制执行节奏
time.Ticker 会按固定间隔发送时间戳到其 C 通道,适合做“心跳”或“调度器”。注意它不会因任务耗时而跳过 tick,若上一次任务未完成,下一次 tick 仍会到来——这正是并发的起点。
常见写法:
- 启动 ticker:
ticker := time.NewTicker(5 * time.Second) - 用
select监听:case 表示到了执行时刻 - 别忘了在退出前调用
ticker.Stop()防止 goroutine 泄漏
每次触发都启一个新 goroutine
在 case 分支中直接用 go func() { ... }() 启动任务,就能实现“每次定时都并发执行”,互不阻塞。
立即学习“go语言免费学习笔记(深入)”;
例如:
go func() {
defer wg.Done()
result := doHeavyWork()
log.Printf("Task done: %v", result)
}()注意:若任务函数需要访问循环变量(如 for 中的 i),务必显式传参,避免闭包捕获问题。
控制并发数量,避免资源耗尽
无限制启 goroutine 可能导致内存暴涨或系统过载。推荐用带缓冲的 channel 或 worker pool 限流。
简单限流示例(最多同时运行 3 个任务):
- 定义信号 channel:
sem := make(chan struct{}, 3) - 每次执行前
sem ,执行完 - 这样可确保同一时刻最多 3 个任务在跑,其余等待空位
优雅关闭与等待完成
程序退出时,需停止 ticker 并等待所有正在运行的任务结束。
- 用
sync.WaitGroup计数活跃 goroutine - 用
context.WithCancel传递取消信号,让长期任务可中断 - 在
defer或 shutdown 函数中调用ticker.Stop()和wg.Wait()
不复杂但容易忽略。










