0

0

如何使用Golang ticker和channel组合实现并发定时器_周期性任务管理

P粉602998670

P粉602998670

发布时间:2026-01-01 14:08:02

|

577人浏览过

|

来源于php中文网

原创

Go中用ticker+channel实现并发定时器的核心是:ticker产生周期时间信号,channel控制启停与参数传递,goroutine实现非阻塞可取消任务;需调用Stop防泄漏,用done或context优雅终止,多任务应独立ticker和channel。

如何使用golang ticker和channel组合实现并发定时器_周期性任务管理

使用 Go 的 tickerchannel 组合实现并发定时器,核心在于:用 time.Ticker 产生周期性时间信号,用 channel 控制启停、传递任务参数或接收结果,再配合 goroutine 实现非阻塞、可取消、可扩展的周期性任务管理。

基础结构:Ticker + Goroutine 启动周期任务

time.Ticker 会按固定间隔向其 C 字段(一个 chan time.Time)发送当前时间。启动一个 goroutine 监听该 channel,即可执行周期逻辑:

ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()

go func() { for range ticker.C { fmt.Println("执行周期任务:", time.Now()) // 这里放你的业务逻辑,如采集指标、清理缓存等 } }()

注意:必须调用 ticker.Stop() 防止 goroutine 泄漏for range ticker.C 是标准写法,自动处理 channel 关闭。

支持动态启停:用 done channel 控制生命周期

直接关闭 ticker.C 不安全,应通过额外的 done channel 控制循环退出:

立即学习go语言免费学习笔记(深入)”;

  • 定义 done := make(chan struct{}) 作为停止信号
  • 在 select 中监听 ticker.Cdone,任一触发即响应
  • 外部只需 close(done) 即可优雅终止

示例:

func runPeriodicTask(interval time.Duration, done chan struct{}) {
    ticker := time.NewTicker(interval)
    defer ticker.Stop()
for {
    select {
    case <-ticker.C:
        fmt.Println("任务运行中...")
        // 执行具体工作(建议加 recover 防 panic 中断)
    case <-done:
        fmt.Println("任务已停止")
        return
    }
}

}

Pi智能演示文档
Pi智能演示文档

领先的AI PPT生成工具

下载

// 使用 done := make(chan struct{}) go runPeriodicTask(3*time.Second, done)

// 停止时 close(done)

并发多任务 + 参数隔离:为每个任务分配独立 channel

若需同时运行多个不同周期、不同参数的任务(例如:每 10s 检查磁盘,每 30s 上报日志),不要共用一个 ticker。应为每个任务创建独立 ticker 和控制 channel:

  • 每个任务封装成函数,接收 interval、参数、done channel 等
  • 用 map 或 slice 管理多个任务的 done channel,便于统一停止
  • 避免在周期函数内做耗时同步操作(如 HTTP 请求),必要时起新 goroutine 或用带超时的 context

简单多任务管理示意:

type Task struct {
    Name     string
    Interval time.Duration
    Action   func()
    Done     chan struct{}
}

func (t *Task) Start() { ticker := time.NewTicker(t.Interval) go func() { defer ticker.Stop() for { select { case <-ticker.C: t.Action() case <-t.Done: return } } }() }

// 启动多个 tasks := []Task{ {Name: "disk-check", Interval: 10 time.Second, Action: checkDisk}, {Name: "log-report", Interval: 30 time.Second, Action: reportLogs}, }

for i := range tasks { tasks[i].Done = make(chan struct{}) tasks[i].Start() }

// 停止全部 for _, t := range tasks { close(t.Done) }

进阶:集成 context 实现超时与取消传播

当周期任务内部含 I/O 操作(如数据库查询、HTTP 调用),推荐用 context.Context 替代裸 done channel,获得超时、截止时间、父子取消链等能力:

  • context.WithTimeoutcontext.WithCancel 包装任务上下文
  • 在 select 中监听 ctx.Done(),而非自定义 done channel
  • 任务函数内所有阻塞操作(如 http.Client.Do)应接受该 ctx

示例片段:

func runWithCtx(ctx context.Context, interval time.Duration, work func(context.Context)) {
    ticker := time.NewTicker(interval)
    defer ticker.Stop()
for {
    select {
    case <-ticker.C:
        // 每次执行都传入新衍生的子 context(可设单次超时)
        childCtx, cancel := context.WithTimeout(ctx, 2*time.Second)
        work(childCtx)
        cancel()
    case <-ctx.Done():
        return
    }
}

}

不复杂但容易忽略:Ticker 的精度受系统调度和 GC 影响,不适合毫秒级强实时场景;高频任务建议用 time.AfterFunc 链式重启,或引入更专业的调度库(如 asynq、gocron)处理复杂依赖与持久化需求。

相关专题

更多
golang如何定义变量
golang如何定义变量

golang定义变量的方法:1、声明变量并赋予初始值“var age int =值”;2、声明变量但不赋初始值“var age int”;3、使用短变量声明“age :=值”等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

174

2024.02.23

golang有哪些数据转换方法
golang有哪些数据转换方法

golang数据转换方法:1、类型转换操作符;2、类型断言;3、字符串和数字之间的转换;4、JSON序列化和反序列化;5、使用标准库进行数据转换;6、使用第三方库进行数据转换;7、自定义数据转换函数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

225

2024.02.23

golang常用库有哪些
golang常用库有哪些

golang常用库有:1、标准库;2、字符串处理库;3、网络库;4、加密库;5、压缩库;6、xml和json解析库;7、日期和时间库;8、数据库操作库;9、文件操作库;10、图像处理库。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

335

2024.02.23

golang和python的区别是什么
golang和python的区别是什么

golang和python的区别是:1、golang是一种编译型语言,而python是一种解释型语言;2、golang天生支持并发编程,而python对并发与并行的支持相对较弱等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

206

2024.03.05

golang是免费的吗
golang是免费的吗

golang是免费的。golang是google开发的一种静态强类型、编译型、并发型,并具有垃圾回收功能的开源编程语言,采用bsd开源协议。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

388

2024.05.21

golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

193

2025.06.09

golang相关判断方法
golang相关判断方法

本专题整合了golang相关判断方法,想了解更详细的相关内容,请阅读下面的文章。

188

2025.06.10

golang数组使用方法
golang数组使用方法

本专题整合了golang数组用法,想了解更多的相关内容,请阅读专题下面的文章。

191

2025.06.17

php源码安装教程大全
php源码安装教程大全

本专题整合了php源码安装教程,阅读专题下面的文章了解更多详细内容。

7

2025.12.31

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Go 教程
Go 教程

共32课时 | 3.1万人学习

Go语言实战之 GraphQL
Go语言实战之 GraphQL

共10课时 | 0.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号