前言

定时器在Go语言应用中使用非常广泛,Go语言的标准库里提供两种类型的计时器,一种是一次性的定时器Timer,另外一种是周期性的定时器Ticker。本文主要来看一下Ticker的用法和实现原理。

Ticker

Ticker是周期性定时器,即周期性的触发一个事件,它会以一个间隔(interval)往channel发送一个事件(当前时间),而channel的接收者可以以固定的时间间隔从channel中读取事件。通过Ticker本身提供的管道将事件传递出去。

应用示例

package mainimport ("fmt""time"
)func main()  {ticker := time.NewTicker(time.Second * 1) //创建一个周期性定时器i := 1for  {fmt.Println(i, "====>", <-ticker.C)if i == 5 {ticker.Stop() //停止定时器break}i++}
}

输出结果:

1 ====> 2022-08-24 15:58:38.971837 +0800 CST m=+1.001366085
2 ====> 2022-08-24 15:58:39.971154 +0800 CST m=+2.000695418
3 ====> 2022-08-24 15:58:40.971633 +0800 CST m=+3.001185460
4 ====> 2022-08-24 15:58:41.97109 +0800 CST m=+4.000654126
5 ====> 2022-08-24 15:58:42.971594 +0800 CST m=+5.001169210

创建定时器

使用NewTicker()方法就可以创建一个周期性定时器,函数如下:

func NewTicker(d Duration) *Ticker

其中参数d即为定时器时间触发的周期,为一个时间段。

停止定时器

使用定时器对外暴露的 Stop 方法就可以停掉一个周期性定时器, 函数如下:

func (t *Ticker) Stop()

该方法会停止计时,停止后不会向定时器的管道中写入事件,但管道并不会被关闭。管道在使用完成后,生命周期结束后会自动释放。

实现原理

数据结构

Ticker的数据结构与Timer完全一致:

通过src/time.sleep.go:Ticker定义了Timer数据结构:

type Ticker struct {C <-chan Timer runtimeTimer
}

它提供了一个channel,在定时时间到达之前,没有数据写入Ticker.C会一直阻塞,直到时间到达,向channel写入系统时间,阻塞解除,可以从中读取数据,这就是一个事件。

我们可以理解为Ticker.C即面向Ticker用户的,Ticker.r是面向底层的定时器实现。

runtimeTimer

runtimeTimer与Timer一样,任务的载体,用于监控定时任务,每创建一个Timer就创建一个runtimeTimer变量,然后把它交给系统进行监控,我们通过设置runtimeTimer过期后的行为来达到定时的目的。

源码包src/time/sleep.go:runtimeTimer定义了其数据结构:

type runtimeTimer struct {tb uintptr                          // 存储当前定时器的数组地址i  int                              // 存储当前定时器的数组下标when   int64                        // 当前定时器触发时间period int64                        // 当前定时器周期触发间隔f      func(interface{}, uintptr)   // 定时器触发时执行的函数arg    interface{}                  // 定时器触发时执行函数传递的参数一seq    uintptr                      // 定时器触发时执行函数传递的参数二(该参数只在网络收发场景下使用)
}

创建Ticker

func NewTicker(d Duration) *Ticker {if d <= 0 {panic(errors.New("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{C: c,r: runtimeTimer{when:   when(d),period: int64(d), // Ticker跟Timer的重要区就是提供了period这个参数,据此决定timer是一次性的,还是周期性的f:      sendTime,arg:    c,},}startTimer(&t.r)return t
}

NewTicker()构造了一个Ticker,然后把Ticker.r通过startTimer()交给系统协程维护。

其中period为事件触发的周期。

停止Ticker

停止Ticker,只是把Ticker从系统协程中移除。

func (t *Ticker) Stop() {stopTimer(&t.r)
}

stopTicker()即通知系统协程把该Ticker移除,即不再监控。系统协程只是移除Ticker并不会关闭管道,以避免用户协程读取错误。

注意:

Ticker在使用完后务必要释放,否则会产生资源泄露,进而会持续消耗CPU资源,最后会把CPU耗尽。

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

Ticker 与 Timer 区别

  • Ticker —— 重复性执行任务非常有用呢
  • Timer —— 用于执行一次性任务

小结

Ticker相关内容总结如下:

  • 使用time.NewTicker()来创建一个定时器;
  • 使用Stop()来停止一个定时器;
  • 定时器使用完毕要释放,否则会产生资源泄露;

教你轻松理解Go Ticker的用法和实现原理相关推荐

  1. 一步步教你轻松学朴素贝叶斯模型算法理论篇1

    一步步教你轻松学朴素贝叶斯模型理论篇1 (白宁超2018年9月3日17:51:32) 导读:朴素贝叶斯模型是机器学习常用的模型算法之一,其在文本分类方面简单易行,且取得不错的分类效果.所以很受欢迎,对 ...

  2. 一步步教你轻松学K-means聚类算法

    一步步教你轻松学K-means聚类算法 (白宁超   2018年9月13日09:10:33) 导读:k-均值算法(英文:k-means clustering),属于比较常用的算法之一,文本首先介绍聚类 ...

  3. 一步步教你轻松学关联规则Apriori算法

    一步步教你轻松学关联规则Apriori算法 (白宁超 2018年10月22日09:51:05) 摘要:先验算法(Apriori Algorithm)是关联规则学习的经典算法之一,常常应用在商业等诸多领 ...

  4. 一步步教你轻松学KNN模型算法

    一步步教你轻松学KNN模型算法 ( 白宁超 2018年7月24日08:52:16 ) 导读:机器学习算法中KNN属于比较简单的典型算法,既可以做聚类又可以做分类使用.本文通过一个模拟的实际案例进行讲解 ...

  5. 教你轻松调DCT和ICC之间Timing与Congestion的一致性

    教你轻松调DCT和ICC之间Timing与Congestion的一致性 文章右侧广告为官方硬广告,与吾爱IC社区无关,用户勿点.点击进去后出现任何损失与社区无关. 转眼间,小编的公众号已经运营了一个月 ...

  6. 教你轻松构建一个可以泡妞的 app

    教你轻松构建一个可以泡妞的 app 此篇文章是比较初级的,主要是指导性内容,不涉及技术.适合非移动端开发人员,公司拍板的老总,有创业梦想的人士.如果你想做个能泡妞的 app 但是不知如何着手,这边文章 ...

  7. 一步步教你轻松学决策树算法

    一步步教你轻松学决策树算法 (白宁超 2018年8月27日16:28:53) 导读:决策树算法是一种基本的分类与回归方法,是最经常使用的算法之一.决策树模型呈树形结构,在分类问题中,表示基于特征对实例 ...

  8. 一步步教你轻松学逻辑回归模型算法

    一步步教你轻松学逻辑回归模型算法 ( 白宁超2018年9月6日15: 01:20) 导读:逻辑回归(Logistic regression)即逻辑模型,属于常见的一种分类算法.本文将从理论介绍开始,搞 ...

  9. 那个软件弹出广告_如何关闭烦人的电脑弹窗广告?5种方法教你轻松解决

    如果要问大家在使用电脑的过程中让人最反感的是什么,我想许多人的回答都会是弹窗广告.一些软件为了给自己创收,完全不顾用户的使用体验,在软件中强行加入广告弹窗模块.这些弹窗广告不仅让人在视觉上烦不胜烦,而 ...

最新文章

  1. Java语言的基础知识9
  2. torch.where用法
  3. mac 上的环境变量配置
  4. MacOS 系统使用命令安装软件包
  5. 【语言处理与Python】2.5WordNet
  6. 6D位姿估计算法Densefusion代码阅读
  7. 【转】HttpCompress
  8. Java的各种中文乱码解决方法
  9. iOS 控制器View加载顺序详细版
  10. Markdown编辑器: 语法、Atom、Word、PPT
  11. 浩鲸科技是外包公司吗_广东电商外包服务公司是什么意思_聚财猫科技
  12. c语言连连看实验报告,连连看c语言实验报告.docx
  13. 各个排序算法(^_^)
  14. var模型的建模步骤python_Python语言之概述建模步骤
  15. 忆我的大学老师----(一)
  16. 在使用百度地图API时,浏览器报错
  17. 为什么论文降重没有效果?
  18. 交通事故现场拍照技巧
  19. The project description file (.project) for 'xxx' is missing.
  20. 【clswindow框架应用】自动移动鼠标避免锁屏,鼠标随机移动防止锁屏、待机、休眠

热门文章

  1. oracle单行子查询返回多个行 order by,单行子查询返回多个行
  2. 大数据练习环境部署(3) - Hadoop集群部署
  3. mysql设置允许远程访问
  4. 三星Galaxy S20:将侧面按钮更改为电源按钮
  5. MATLAB浮点数详解
  6. 绿米Aqara智能设备还能这样玩?
  7. 基于知识图谱的表示学习——Trans系列算法介绍(一)
  8. 微信内置浏览器中使用一键打电话功能
  9. vFlat Scan – 可能是最快捷的纸质书扫描应用,一次 2页,居然还能移除手指头[iOS/Android]
  10. 资源分享:17 张程序员专属高清壁纸