文章目录

  • Golang 定时器Timer和Ticker
    • time.Timer
      • time.NewTimer()实例
    • time.AfterFunc
    • time.Ticker
      • time.NewTicker()实例
      • [重要]time.NewTicker()使用总结

Golang 定时器Timer和Ticker

Golang 定时器包括:一次性定时器(Timer)和周期性定时器(Ticker)。

编程中经常会通过timer和ticker、AfterFunc定时器NewTicker是设定每隔多长时间触发的,是连续触发,而计时器NewTimer是等待多长时间触发的,只触发一次,两者是不同的。等待时间函数AfterFunc是在After基础上加了一个回调函数,是等待时间到来后在另外一个goroutine协程里调用。

  • Timer
    timer创建有两种方式,time.NewTimer(Duration) 和time.After(Duration)。 后者只是对前者的一个包装。
    timer到固定时间后会执行一次,请注意是一次,而不是多次。但是可以通过reset来实现每隔固定时间段执行。使用timer定时器,超时后需要重置,才能继续触发。

  • Ticker
    ticker只要定义完成,从此刻开始计时,不需要任何其他的操作,每隔固定时间都会触发。它会以一个间隔(interval)往通道发送当前时间,而通道的接收者可以以固定的时间间隔从通道中读取时间。

time.Timer

首先我们看Timer的结构定义:

type Timer struct {C <-chan Timer runtimeTimer
}

其中有一个C的只读channel,还有一个runtimeTimer类型的结构体,再看一下这个结构的具体结构:

type runtimeTimer struct {tb uintptri  intwhen   int64period int64f      func(interface{}, uintptr) // NOTE: must not be closurearg    interface{}seq    uintptr
}

在使用定时timer的时候都是通过 NewTimer 或 AfterFunc 函数来获取。

func NewTimer(d Duration) *Timer {c := make(chan Time, 1)t := &Timer{C: c,r: runtimeTimer{when: when(d), //表示达到时间段d时候调用ff:    sendTime,  // f表示一个函数调用,这里的sendTime表示d时间到达时向Timer.C发送当前的时间arg:  c,  // arg表示在调用f的时候把参数arg传递给f,c就是用来接受sendTime发送时间的},}startTimer(&t.r)return t
}

定时器的具体实现逻辑,都在 runtime 中的 time.go 中,它的实现,没有采用经典 Unix 间隔定时器 setitimer 系统调用,也没有 采用 POSIX间隔式定时器(相关系统调用:timer_create、timer_settime 和 timer_delete),而是通过四叉树堆(heep)实现的(runtimeTimer 结构中的i字段,表示在堆中的索引)。通过构建一个最小堆,保证最快拿到到期了的定时器执行。定时器的执行,在专门的 goroutine 中进行的:go timerproc()。有兴趣的同学,可以阅读 runtime/time.go 的。

time.NewTimer()实例

package mainimport ("fmt""time"
)func main() {myTimer := time.NewTimer(time.Second * 2) // 启动定时器var i int = 0for {select {case <-myTimer.C:i++fmt.Println("count: ", i)myTimer.Reset(time.Second * 2) // 每次使用完后需要人为重置下}}// 不再使用了,结束它myTimer.Stop()
}

使用timer定时器,超时后需要重置,才能继续触发。

time.AfterFunc

Go语言的AfterFunc()函数用于等待经过的时间,此后,它将在其自己的go-routine中调用已定义的函数“f”。此外,此函数在时间包下定义。在这里,您需要导入“time”包才能使用这些函数。

func AfterFunc(d Duration, f func()) *Timer

例子:

// Golang program to illustrate the usage of
// AfterFunc() function // Including main package
package main // Importing fmt and time
import ( "fmt""time"
) // Main function
func main() { // Defining duration parameter of // AfterFunc() method DurationOfTime:= time.Duration(3) * time.Second // Defining function parameter of // AfterFunc() method f:= func() { // Printed when its called by the // AfterFunc() method in the time // stated above fmt.Println("Function called by "+ "AfterFunc() after 3 seconds") } // Calling AfterFunc() method with its // parameter Timer1:= time.AfterFunc(DurationOfTime, f) // Calling stop method  // w.r.to Timer1 defer Timer1.Stop() // Calling sleep method time.Sleep(10 * time.Second)
}

time.Ticker

官网:https://pkg.go.dev/time#NewTicker

Golang time.Timer and time.Ticker
参考URL: https://www.jianshu.com/p/2b4686b8de4a

time.NewTicker()实例

官网:https://pkg.go.dev/time#NewTicker

官方demo

package mainimport ("fmt""time"
)func main() {ticker := time.NewTicker(time.Second)defer ticker.Stop()done := make(chan bool)go func() {time.Sleep(10 * time.Second)done <- true}()for {select {case <-done:fmt.Println("Done!")returncase t := <-ticker.C:fmt.Println("Current time: ", t)}}
}

Ticker是一个周期触发定时的计时器,它会按照一个时间间隔往channel发送系统当前时间,而channel的接收者可以以固定的时间间隔从channel中读取事件。

相关函数:
NewTicker() 返回一个新的Ticker,该Ticker包含一个通道字段,并会每隔时间段d就向该通道发送当时的时间。它会调整时间间隔或者丢弃tick信息以适应反应慢的接收者。如果d<=0会panic。关闭该Ticker可以释放相关资源。
Stop() 关闭一个Ticker。在关闭后,将不会发送更多的tick信息。Stop不会关闭通道t.C,以避免从该通道的读取不正确的成功

demo2: time.NewTicker 周期时间到了,但是之前程序没有执行完,怎么处理?

package mainimport ("fmt""time"
)func main() {ticker := time.NewTicker(time.Second)defer ticker.Stop()done := make(chan bool)go func() {time.Sleep(10 * time.Second)done <- true}()for {select {case <-done:fmt.Println("Done!")returncase t := <-ticker.C:fmt.Println("Current time: ", t)time.Sleep(4 * time.Second)}}
}

经过代码验证:time.NewTicker定时触发执行任务,当下一次执行到来而当前任务还没有执行结束时,会等待当前任务执行完毕后再执行下一次任务。

[重要]time.NewTicker()使用总结

  1. ticker 创建完之后,不是马上就有一个 tick,第一个 tick 在 x 秒(你自己写的)之后
  2. Go语言的定时器实质是单向通道,time.Timer结构体类型中有一个time.Time类型的单向chan。
  3. **time.NewTicker定时触发执行任务,当下一次执行到来而当前任务还没有执行结束时,会等待当前任务执行完毕后再执行下一次任务。**查阅go官网的文档和经过代码验证。
  4. t.Stop()在这里并不会停止定时器。这是因为Stop会停止Timer,停止后,Timer不会再被发送,但是Stop不会关闭通道,防止读取通道发生错误。
    官方说明: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”.
    如果想停止定时器,只能让go程序自动结束。
  5. Ticker 跟 Timer 的不同之处,就在于 Ticker 时间达到后不需要人为调用 Reset 方法,会自动续期。

Go (Golang) 语言-Golang 定时器Timer和Ticker、time.AfterFunc、time.NewTicker()实例相关推荐

  1. Golang 定时器timer和ticker

    两种类型的定时器:ticker和timer.两者有什么区别呢?请看如下代码: tickerpackage mainimport ("fmt""time" )fu ...

  2. 定时器Timer和Ticker

    Timer Timer是一个定时器,代表未来的一个单一事件,通过Timer本身提供的管道将事件传递出去,言外之意是只执行一次. Timer的数据结构如下: type Timer struct {C & ...

  3. golang延时_Golang 定时器底层实现深度剖析

    本文将基于 Golang 源码对 Timer 的底层实现进行深度剖析.主要包含以下内容: 1. Timer 和 Ticker 在 Golang 中的底层实现细节,包括数据结构等选型. 2. 分析 ti ...

  4. Golang当中的定时器

    定时器 前言 定时器的基本使用 前言 在平时写代码的时候,我们经常会遇到在将来某个时间点或者间隔一段时间重复执行函数.这个时候我们就可以考虑使用定时器.本片文章主要介绍一下golang当中的几个常用的 ...

  5. golang中的定时器

    定时器 type Timer struct {C<-chan Timer runtimeTimer } Timer 一个定时器,代表未来的一个单一事件,你可以告诉timer你要等待多长时间,它提 ...

  6. 最新golang语言面试题总结(一)

    1.go中make和new区别 new: 分配内存.内存里存的值是对应类型的零值. 只有一个参数.参数是分配的内存空间所存储的变量类型,Go语言里的任何类型都可以是new的参数,比如int, 数组,结 ...

  7. Golang语言全栈开发视频教程全集

    基础课: 语言基础第01天(变量和基本类型) 语言基础第02天(运算符和流程控制) 语言基础第03天(循环函数和工程管理) 语言基础第04天(工程管理和数组) 语言基础第05天(切片和map) 语言基 ...

  8. log包在Golang语言的标准库中是怎么使用的?

    Golang 语言的标准库中提供了一个简单的 log 日志包,它不仅提供了很多函数,还定义了一个包含很多方法的类型 Logger.但是它也有缺点,比如不支持区分日志级别,不支持日志文件切割等. 01. ...

  9. 语言与golang语言运行速度_Golang语言情怀第3期 Go 语言数据类型

    本期给大家聊下Go语言的数据类型有哪些,数据类型用于声明函数和变量.数据类型的出现是为了把数据分成所需内存大小不同的数据,编程的时候需要用大数据的时候才需要申请大内存,就可以充分利用内存. Go 语言 ...

最新文章

  1. 批处理+定时任务实现定时休息提醒
  2. hbase 客户端_HBase架构与原理详解
  3. mysql5.7.24免安装版配置_mysql5.7.20免安装版配置方法图文教程
  4. 开源贡献 计算_通过Hacktoberfest的镜头看开源贡献的状态
  5. mysql内置时间函数大全_MySQL 的时间函数 大全
  6. 多元线性回归数据集_TensorFlow学习Program1——13.实现一元、多元线性回归(基于房价数据集)...
  7. [转载]网站分析的最基本度量(3)——网站分析工具如何辨别UV
  8. 在Apache环境下成功的运行ASP.NET
  9. linux自动补全快捷键,linux常用快捷键
  10. 抖音:时间熔炉的诞生
  11. 机器人运动学与动力学
  12. idea中字体由繁体变简体
  13. el-checkbox-group 的坑
  14. 张正友标定法过程推导笔记
  15. android EditText的美化
  16. PyQt5 给QLabel添加点击事件
  17. 手机浏览器上网谁最快?手机浏览器速度测评
  18. 用java编写注册界面_java编写一个注册界面的方法
  19. Excel VBA单元格数据自增1
  20. vs community 2019安装失败问题解决

热门文章

  1. matlab合理分配席位_走进民航一线——首都机场机位分配员的24小时
  2. 面试集锦-------LRU,LFU手撕算法
  3. Linux下vi进入一个文件后,按Esc+q无法退出编辑模式的解决办法。
  4. lammps分子动力学 入门到进阶
  5. FPGA学习5-PL和PS互联
  6. 【Axure篇】(二)Axure RP9日期控件制作(多种格式)
  7. c语言排列组合还可以这样求
  8. mongrel服务器
  9. clamav Java_ClamAV安装使用详解
  10. [sql server][基础] 链接服务器