Go语言中Timer与Ticker的区别及Cron定时任务实战

码头散步
码头散步
发布时间:2026-10-15 | 6人浏览过
原创

在Go语言开发中,处理定时逻辑通常涉及标准库time与第三方cron工具。本文梳理了time.NewTimer与NewTicker的核心差异,并展示使用robfig/cron库配置周期性调度任务的完整实例。

Timer与Ticker的原理差异

Golang的 time 包提供了两种基础的定时器:Ticker 用于固定间隔重复执行,而 Timer 专用于一次性延时触发。理解两者的底层行为是避免资源泄漏的关键。

  • Ticker(周期性):每隔特定时间段向通道发送信号。除非显式调用 Stop(),否则它将一直运行。
  • Timer(单次性):在设定的持续时间后触发一次事件。若需复用,必须手动调用 Reset();若不再需要,应及时 Stop()。

Timer的初始化与重置操作

Timer 适合执行“延迟执行”或“超时等待”的业务逻辑。其初始化为一次性触发,重置后可复用计时。

  1. 单次触发示例:创建3秒后自动关闭的Timer,并在通道接收前阻塞主进程。
package main

import (
    "fmt"
    "time"
)

func main() {

    //设置定时器为3秒
    timer := time.NewTimer(3 * time.Second)
    fmt.Println("当前时间为:", time.Now())

    t := <-timer.C //从定时器拿数据
    fmt.Println("当前时间为:", t)
}

Ticker的循环监听机制

Ticker 适用于轮询或定长周期的工作流。由于它会不断向通道写入值,必须在 Goroutine 中处理以防止主线程阻塞。

  1. 周期性触发示例:每3秒向通道投递时间戳,主循环中保持程序存活以配合子协程运行。
package main

import (
    "fmt"
    "time"
)

func main() {

    //创建一个周期性的定时器
    ticker := time.NewTicker(3 * time.Second)
    fmt.Println("当前时间为:", time.Now())

    go func() {
        for {
            //从定时器中获取数据
            t := <-ticker.C
            fmt.Println("当前时间为:", t)
        }
    }()

    for {
        time.Sleep(time.Second * 1)
    }
}

引入Robfig/Cron构建复杂定时任务

当需要基于Unix Cron语法(如每天凌晨执行)或更高级的时间规则时,应借助 github.com/robfig/cron 库。它支持函数注册、对象方法调用及动态解析。

package main

import (
	"github.com/robfig/cron"
	"log"
	"time"
)

func main() {
	//cron1()
	//cron2()
	cron3()

	select {}
}

func cron1()  {
	log.Println("Starting...")
	c := cron.New()
	c.AddFunc("* * * * * *", func() {
		log.Println("Run models.CleanAllTag...")
	})
	c.AddFunc("* * * * * *", func() {
		log.Println("Run models.CleanAllArticle...")
	})

	c.Start()

	t1 := time.NewTimer(time.Second * 10)
	for {
	select {
	case <-t1.C:
	    t1.Reset(time.Second * 10)
	}
	}
}

func cron2()  {
	log.Println("Starting...")
	c := cron.New()  // 新建一个定时任务对象
	c.AddFunc("* * * * * *", func() {
		log.Println("hello world")
	})  // 给对象增加定时任务
	c.Start()
	time.Sleep(10 * time.Second)
	c.Stop()
}

func cron3()  {
	log.Println("Starting...")

	c := cron.New()
	h := Hello{"I Love You!"}
	// 添加定时任务
	c.AddJob("*/2 * * * * *", h)
	// 添加定时任务 5秒执行一次
	c.AddFunc("*/5 * * * * *", func() {
		log.Println("hello word")
	})

	s, err := cron.Parse("*/3 * * * * *")
	if err != nil {
		log.Println("Parse error")
	}
	h2 := Hello{"I Hate You!"}
	c.Schedule(s, h2)
	// 其中任务
	c.Start()
	// 关闭任务
	defer c.Stop()
}

type Hello struct {
	Str string
}

func(h Hello) Run() {
	log.Println(h.Str)
}

以上就是Go语言中Timer与Ticker的区别及Cron定时任务实战的详细内容,更多关于Go语言定时调度的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表