news 2026/6/9 22:45:43

Go进阶之定时器Ticker

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Go进阶之定时器Ticker

Ticker是周期性定时器.即周期性的触发一个事件.通过Ticker本身提供的管道将事件

传递出去.

Ticker数据结构:

源码位置:src/time/tick.go

type Ticker struct { C <-chan Time // The channel on which the ticks are delivered. initTicker bool }

Ticker对外仅暴露了一个channel.当指定时间到来时就往该channel中写入系统时

间.即一个事件.

1.简单定时任务:

func main() { ticker := time.NewTicker(1 * time.Second) defer ticker.Stop() for range ticker.C { log.Println("tick") } }

执行结果:

定时聚合任务:

示例:

func TickerLaunch() { //5分钟执行一次. ticker := time.NewTicker(5 * time.Minute) defer ticker.Stop() maxPassenger := 30 passengers := make([]string, 0, maxPassenger) for { passenger := GetNewPassenger() if passenger != "" { passengers = append(passengers, passenger) } else { time.Sleep(1 * time.Second) } select { case <-ticker.C: Launch(passengers) passengers = []string{} default: if len(passengers) >= maxPassenger { Launch(passengers) passengers = []string{} } } } } func Launch(passengers []string) { for i := range passengers { fmt.Println(passengers[i], "发车了") } } func GetNewPassenger() string { return "乘客" }

2.Ticker对外接口:

1)创建定时器:

源码位置:src/time/tick.go

func NewTicker(d Duration) *Ticker { if d <= 0 { panic("non-positive interval for NewTicker") } // Give the channel a 1-element time buffer. // If the client falls behind while reading, we drop ticks // on the floor until the client catches up. c := make(chan Time, 1) t := (*Ticker)(unsafe.Pointer(newTimer(when(d), int64(d), sendTime, c, syncTimer(c)))) t.C = c return t }

2).停止定时器:

源码位置:src/time/tick.go

// Stop turns off a ticker. After Stop, no more ticks will be sent. // Stop does not close the channel, to prevent a concurrent goroutine // reading from the channel from seeing an erroneous "tick". func (t *Ticker) Stop() { if !t.initTicker { // This is misuse, and the same for time.Timer would panic, // but this didn't always panic, and we keep it not panicking // to avoid breaking old programs. See issue 21874. return } stopTimer((*Timer)(unsafe.Pointer(t))) }

流程图:

总流程图:

3.简单接口:

在有些场景下.启动一个定时器后.该定时器永远不会停止.比如定时轮询任务.此时可

以使用一个简单的Tick函数来获取定时器的管道.函数如下:

源码位置:src/runtime/tick.go

func Tick(d Duration) <-chan Time { if d <= 0 { return nil } return NewTicker(d).C }

从源码可以看出其实是创建了一个Ticker.然后只返回了管道.并没有返回ticker.所以

没有办法停止.

4.错误示例:

当Ticker用于for循环时.很容易出现意想不到的资源泄漏问题.

示例:

func WrongTicker() { for { select { case <-time.Tick(time.Second): log.Printf("resource leak!") } } }

上面的代码.select每次检测case语句都会创建一个定时器.for循环又会不断的执行

select语句.系统里会有越来越多的定时器不断地消耗CPU资源.最终CPU资源被耗

尽.

兜兜转转.何以解忧.

如果大家喜欢我的分享的话.可以关注我的微信公众号

念何架构之路

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/10 11:08:41

IAR EWARM STM32工程配置全解析:从芯片选型到LED闪烁

1. IAR EWARM工程配置全流程解析在STM32嵌入式开发实践中&#xff0c;IAR Embedded Workbench&#xff08;EWARM&#xff09;虽非当前主流推荐工具链&#xff0c;但其在工业控制、汽车电子等对代码体积与执行效率有严苛要求的领域仍具不可替代性。理解IAR工程配置逻辑&#xff…

作者头像 李华
网站建设 2026/6/10 11:26:13

文脉定序入门指南:理解Cross-Attention重排序与向量召回的本质差异

文脉定序入门指南&#xff1a;理解Cross-Attention重排序与向量召回的本质差异 你是不是经常遇到这样的问题&#xff1a;在知识库或者搜索引擎里&#xff0c;明明输入了很准确的问题&#xff0c;系统也返回了一大堆结果&#xff0c;但真正能回答你问题的答案&#xff0c;却排在…

作者头像 李华
网站建设 2026/6/10 13:45:30

MusePublic+STM32CubeMX的端侧AI开发

MusePublicSTM32CubeMX的端侧AI开发效果展示 1. 离线语音识别在MCU上跑起来了 第一次看到MusePublic模型在STM32F407上成功识别出“打开灯光”这句话时&#xff0c;我盯着串口打印出来的结果看了好几秒。没有网络连接&#xff0c;没有云端服务&#xff0c;只有一块不到十块钱…

作者头像 李华
网站建设 2026/6/10 11:30:08

幻境·流金保姆级教程:15步生成1024高清图的Z-Image全流程详解

幻境流金保姆级教程&#xff1a;15步生成1024高清图的Z-Image全流程详解 “流光瞬息&#xff0c;影画幻成。” 如果你正在寻找一个能快速将脑海中的画面变成高清大图的工具&#xff0c;那么“幻境流金”可能就是你的答案。它不像传统AI绘画工具那样需要漫长的等待和复杂的参数…

作者头像 李华
网站建设 2026/6/10 11:28:32

SenseVoice-small-onnx镜像免配置教程:无需下载模型直接启动服务

SenseVoice-small-onnx镜像免配置教程&#xff1a;无需下载模型直接启动服务 1. 引言 你是不是也遇到过这种情况&#xff1a;想体验一个最新的语音识别模型&#xff0c;结果光是下载模型文件就要等上半天&#xff0c;动辄几个G的大小&#xff0c;网速慢的时候简直让人抓狂。好…

作者头像 李华
网站建设 2026/6/10 9:21:40

Qwen3-Reranker-0.6B代码检索效果实测:准确率提升35%

Qwen3-Reranker-0.6B代码检索效果实测&#xff1a;准确率提升35% 1. 导语&#xff1a;当代码搜索遇到瓶颈 你有没有过这样的经历&#xff1f;在庞大的项目代码库里&#xff0c;想找一个实现特定功能的函数&#xff0c;比如“用户登录验证”&#xff0c;结果搜索工具给你返回了…

作者头像 李华