当前位置:首页 > 文章列表 > Golang > Go教程 > Go time.Ticker 用在长循环里怎么保证退出时停止

Go time.Ticker 用在长循环里怎么保证退出时停止

来源:17golang原创 2026-09-08 02:25:11 0浏览 收藏

Go 的 time.Ticker 适合给长循环提供周期事件,但“停止 ticker”和“结束循环”是两个动作。可靠写法是让循环同时监听 ticker.C 与退出信号,在拥有 ticker 的函数里执行 defer ticker.Stop(),再用完成通知告诉调用方 goroutine 已经退出。这样即使循环当前没有等到下一次 tick,也能及时收尾。

只要长循环仍然由当前函数负责,就由当前函数创建并停止 ticker;退出条件放进同一个 select,复用周期用 Reset,不能用关闭 ticker.C 来表示结束。
要点速览
  • Stop 负责停止后续 tick,不负责关闭 ticker.C,所以循环必须另有退出条件。
  • defer ticker.Stop() 适合绑定创建者的生命周期;若要确认 goroutine 结束,再增加 done 通知。
  • Reset 会先停止再设置新周期,周期必须大于零,并且应由一个明确的 owner 串行调用。

一、先把退出信号和 ticker 放在同一层

最容易出问题的代码是只写 for range ticker.C。这个循环只能等时间事件,业务停止时没有第二个出口。把退出通道和 ticker.C 放在同一个 select 中,停止条件才与工作事件处在同一控制边界。

Go time.Ticker 长循环中 NewTicker、Ticker.C、select、done 和 workerLoop 的静态关系
图1:查看 workerLoop 中 NewTicker、Ticker.C、select 与 done 的静态关系,退出信号和时间事件由同一循环控制。
func runLoop(done 

NewTicker 的周期必须大于零,否则会 panic。示例中的 done 只负责表达退出意图,真正的清理由函数返回后的 defer ticker.Stop() 完成;不要把 done 当作 ticker 的替代品。

二、退出路径里调用 Stop 并等待循环结束

如果 runLoop 在独立 goroutine 中运行,调用方发送停止信号后还需要知道它何时真正退出。可以增加一个只关闭一次的 finished 通知。Stop 不关闭 ticker.C,这是刻意设计,用来避免接收方把 channel 关闭误判成一次业务 tick。

func startWorker(ctx context.Context, interval time.Duration) 

调用方可以先取消 ctx,再等待 finished。若还有连接、文件或 worker 池要释放,放在收到 finished 之后更稳妥,因为这时循环已经不可能再次使用这些资源。

三、复用长生命周期 ticker 时用 Reset

同一个 worker 只是临时改变周期时,不必重新创建 ticker 并覆盖旧引用。ticker.Reset(interval) 会停止当前计时并以新周期重新计时,下一次 tick 会在新周期之后到达。Reset 的参数同样必须大于零,而且不要让多个 goroutine 同时修改同一个 ticker。

Go ticker.Stop、ticker.Reset、runLoop、context.Done、cleanup 和 time.Duration 的静态生命周期关系
图2:查看 ticker.Reset 的复用配置边界与 ticker.Stop、context.Done、cleanup 的退出关系。
func applyInterval(ticker *time.Ticker, interval time.Duration) {
	// 由 ticker 的唯一 owner 串行调整周期,避免并发 Reset。
	if interval 

如果新周期来自配置热更新,要先把配置更新消息交给负责循环的 goroutine,再由它调用 Reset。若 ticker 的所有权已经转移或循环准备退出,直接走 Stop,不要一边退出一边 Reset。

四、根据慢处理和并发场景做收尾检查

每次 tick 到来并不代表每次任务都必须执行。官方文档说明,接收方处理较慢时,ticker 会调整间隔或丢弃 tick 来追赶时间;因此 ticker 更适合“按周期触发一次检查”,不适合作为不能丢失的任务队列。必须逐次处理时,应把任务放进队列并单独确认积压。

检查项正确判断常见误区
停止动作owner 调用 Stop等待 ticker.C 自己关闭
退出确认等待 finishedWaitGroup发送取消后立刻释放共享资源
周期调整由同一循环串行调用 Reset多个 goroutine 共享并发修改
任务可靠性把不可丢任务交给队列把每个 tick 当成必达消息

Go 1.23 起,垃圾回收器可以回收不再可达且未停止的 ticker,但这不改变显式 Stop 的工程价值:它表达生命周期结束,也让代码审查能直接看出资源边界。尤其是长循环、测试替身和热更新 worker,不要依赖垃圾回收来代替退出协议。

常见问题

Stop 之后为什么不能从 ticker.C 收到“关闭”信号?

因为 Stop 不关闭 channel。循环应该监听自己的 donecontext.Done(),不能通过 range 等待 ticker.C 结束。

长任务执行时收到退出信号,能立即停止 refreshCache 吗?

不能自动停止。应把 context 继续传给任务,让任务内部检查取消;否则外层循环只能在本次处理返回后退出。

可以用 time.Tick 代替 NewTicker 吗?

只需要一个无法主动调整周期的简单循环时可以,但需要显式 Stop、Reset 或等待退出确认时,应使用 NewTicker,保留 ticker 对象的所有权。

相关事实可从 Go time 包文档核对:NewTickerStopReset 的生命周期语义分别不同。最终审查只问四件事:谁创建、谁停止、谁接收、谁确认退出。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
雾中海边灯塔手机壁纸怎么做出怎么让灯塔在低对比雾气中保持主体清晰雾中海边灯塔手机壁纸怎么做出怎么让灯塔在低对比雾气中保持主体清晰
上一篇
雾中海边灯塔手机壁纸怎么做出怎么让灯塔在低对比雾气中保持主体清晰
MySQL JSON 路径不存在时怎么区分 NULL 和空数组
下一篇
MySQL JSON 路径不存在时怎么区分 NULL 和空数组
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    14次使用
  • SuperCLUE中文大模型评测基准:功能、能力维度与应用指南
    SuperCLUE
    SuperCLUE是权威的中文大语言模型综合评测基准,涵盖语言理解、知识应用、AI Agent智能体及安全性等12项核心能力。通过多轮对话与客观测试,定期发布榜单与技术报告,为模型研发、优化及行业选型提供科学依据。
    174次使用
  • C-Eval中文评测基准:大语言模型多学科能力评估指南
    C-Eval
    深入了解C-Eval中文评估套件,涵盖52个学科与4级难度。本文详解其功能特点、Zero-shot/Few-shot使用方法及代码示例,助您全面评测LLM中文理解与泛化能力。
    109次使用
  • AI Prompt Library:免费AI提示词库,助力ChatGPT高效创作与营销
    AI Prompt Library
    探索AI Prompt Library免费资源库,涵盖营销、写作及多场景AI提示词。兼容ChatGPT、Claude等工具,一键复制优化输出,提升工作效率。
    37次使用
  • Generrated:DALL·E 2/3 AI绘画提示词灵感库与图像对比平台
    Generrated
    Generrated汇集9300+张DALL·E生成图像及对应提示词,支持查看完整图集、对比DALL·E 2与3版本差异,是AI绘图新手学习Prompt设计与获取创作灵感的实用工具。
    13次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码