17370845950

如何在Golang中实现定时任务并发执行_使用ticker和协程组合
核心是用 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 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()

不复杂但容易忽略。