首页 文章 精选 留言 我的

精选列表

搜索[Go语言],共10000篇文章
优秀的个人博客,低调大师

Go Ticker正确的使用姿势

简介 Ticker是周期性定时器,即周期性的触发一个事件,通过Ticker本身提供的管道将事件传递出去。 Ticker的数据结构与Timer完全一致: type Ticker struct { C <-chan Time r runtimeTimer } Ticker对外仅暴露一个channel,指定的时间到来时就往该channel中写入系统时间,也即一个事件。 在创建Ticker时会指定一个时间,作为事件触发的周期。这也是Ticker与Timer的最主要的区别。 另外,ticker的英文原意是钟表的"滴哒"声,钟表周期性的产生"滴哒"声,也即周期性的产生事件。 使用场景 简单定时任务 有时,我们希望定时执行一个任务,这时就可以使用ticker来完成。 下面代码演示,每隔1s记录一次日志: // TickerDemo 用于演示ticker基础用法 func TickerDemo() { ticker := time.NewTicker(1 * time.Second) defer ticker.Stop() for range ticker.C { log.Println("Ticker tick.") } } 上述代码中,for range ticker.C会持续从管道中获取事件,收到事件后打印一行日志,如果管道中没有数据会阻塞等待事件,由于ticker会周期性的向管道中写入事件,所以上述程序会周期性的打印日志。 定时聚合任务 有时,我们希望把一些任务打包进行批量处理。比如,公交车发车场景: 公交车每隔5分钟发一班,不管是否已坐满乘客; 已坐满乘客情况下,不足5分钟也发车; 下面代码演示公交车发车场景: // TickerLaunch用于演示ticker聚合任务用法 func TickerLaunch() { ticker := time.NewTicker(5 * time.Minute) 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{} } } } } 上面代码中for循环负责接待乘客上车,并决定是否要发车。每当乘客上车,select语句会先判断ticker.C中是否有数据,有数据则代表发车时间已到,如果没有数据,则判断车是否已坐满,坐满后仍然发车。 Ticker对外接口 创建定时器 使用NewTicker方法就可以创建一个周期性定时器,函数原型如下: func NewTicker(d Duration) *Ticker 其中参数d即为定时器事件触发的周期。 停止定时器 使用定时器对外暴露的Stop方法就可以停掉一个周期性定时器,函数原型如下: func (t *Ticker) Stop() 需要注意的是,该方法会停止计时,意味着不会向定时器的管道中写入事件,但管道并不会被关闭。管道在使用完成后,生命周期结束后会自动释放。 Ticker在使用完后务必要释放,否则会产生资源泄露,进而会持续消耗CPU资源,最后会把CPU耗尽。更详细的信息,后面我们研究Ticker实现原理时再详细分析。 简单接口 部分场景下,我们启动一个定时器并且永远不会停止,比如定时轮询任务,此时可以使用一个简单的Tick函数来获取定时器的管道,函数原型如下: func Tick(d Duration) <-chan Time 这个函数内部实际还是创建一个Ticker,但并不会返回出来,所以没有手段来停止该Ticker。所以,一定要考虑具体的使用场景。 错误示例 Ticker用于for循环时,很容易出现意想不到的资源泄露问题,下面代码演示了一个泄露问题: func WrongTicker() { for { select { case <-time.Tick(1 * time.Second): log.Printf("Resource leak!") } } } 上面代码,select每次检测case语句时都会创建一个定时器,for循环又会不断的执行select语句,所以系统里会有越来越多的定时器不断的消耗CPU资源,最终CPU会被耗尽。 总结 Ticker相关内容总结如下: 使用time.NewTicker()来创建一个定时器; 使用Stop()来停止一个定时器; 定时器使用完毕要释放,否则会产生资源泄露; 赠人玫瑰手留余香,如果觉得不错请给个赞~ 本篇文章已归档到GitHub项目,求星~ 点我即达

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册