from: https://www.kancloud.cn/digest/batu-go/153534

定时器

在time包中有两个函数可以帮助我们初始化time.Timer

time.Newtimer函数

初始化一个到期时间据此时的间隔为3小时30分的定时器

t := time.Newtimer(3*time.Hour + 30*time.Minute)
注意,这里的变量t是*time.NewTimer类型的,这个指针类型的方法集合包含两个方法

  • Rest
    用于重置定时器。该方法返回一个bool类型的值
  • Stop
    用来停止定时器。该方法返回一个bool类型的值,如果返回false,说明该定时器在之前已经到期或者已经被停止了,反之返回true。

通过定时器的字段C,我们可以及时得知定时器到期的这个事件来临,C是一个chan time.Time类型的缓冲通道,一旦触及到期时间,定时器就会向自己的C字段发送一个time.Time类型的元素值

示例一:一个简单定时器

package mainimport ("fmt""time"
)func main(){//初始化定时器t := time.NewTimer(2 * time.Second)//当前时间now := time.Now()fmt.Printf("Now time : %v.\n", now)expire := <- t.Cfmt.Printf("Expiration time: %v.\n", expire)
}

Now time : 2015-10-31 01:19:07.210771347 +0800 CST.
Expiration time: 2015-10-31 01:19:09.215489592 +0800 CST.

示例二:我们在改造下之前的那个简单超时操作

package mainimport ("fmt""time"
)
func main(){//初始化通道ch11 := make(chan int, 1000)sign := make(chan byte, 1)//给ch11通道写入数据for i := 0; i < 1000; i++ {ch11 <- i}//单独起一个Goroutine执行selectgo func(){var e intok := true//首先声明一个*time.Timer类型的值,然后在相关case之后声明的匿名函数中尽可能的复用它var timer *time.Timerfor{select {case e = <- ch11:fmt.Printf("ch11 -> %d\n",e)case <- func() <-chan time.Time {if timer == nil{//初始化到期时间据此间隔1ms的定时器timer = time.NewTimer(time.Millisecond)}else {//复用,通过Reset方法重置定时器timer.Reset(time.Millisecond)}//得知定时器到期事件来临时,返回结果return timer.C}():fmt.Println("Timeout.")ok = falsebreak}//终止for循环if !ok {sign <- 0break}}}()//惯用手法,读取sign通道数据,为了等待select的Goroutine执行。<- sign
}

time.After函数

time.After函数, 表示多少时间之后,但是在取出channel内容之前不阻塞,后续程序可以继续执行。鉴于After特性,其通常用来处理程序超时问题。

package mainimport ("fmt""time"
)func main(){ch1 := make(chan int, 1)ch2 := make(chan int, 1)select {case e1 := <-ch1://如果ch1通道成功读取数据,则执行该case处理语句fmt.Printf("1th case is selected. e1=%v",e1)case e2 := <-ch2://如果ch2通道成功读取数据,则执行该case处理语句fmt.Printf("2th case is selected. e2=%v",e2)case <- time.After(2 * time.Second):fmt.Println("Timed out")}
}

Timed out

  • time.Sleep函数,表示休眠多少时间,休眠时处于阻塞状态,后续程序无法执行.
    time.Afterfunc函数

示例三:自定义定时器

package mainimport ("fmt""time"
)
func main(){var t *time.Timerf := func(){fmt.Printf("Expiration time : %v.\n", time.Now())fmt.Printf("C`s len: %d\n", len(t.C))}t = time.AfterFunc(1*time.Second, f)//让当前Goroutine 睡眠2s,确保大于内容的完整//这样做原因是,time.AfterFunc的调用不会被阻塞。它会以一部的方式在到期事件来临执行我们自定义函数f。time.Sleep(2 * time.Second)
}

Expiration time : 2015-10-31 01:04:42.579988801 +0800 CST.
C`s len: 0

第二行打印内容说明:定时器的字段C并没有缓冲任何元素值。这也说明了,在给定了自定义函数后,默认的处理方法(向C发送代表绝对到期时间的元素值)就不会被执行了。

断续器

结构体类型time.Ticker表示了断续器的静态结构。
就是周期性的传达到期时间的装置。这种装置的行为方式与仅有秒针的钟表有些类似,只不过间隔时间可以不是1s。
初始化一个断续器

var ticker *timeTicker = time.NewTicker(time.Second)

示例一:使用时间控制停止ticke

package mainimport ("fmt""time"
)func main(){ //初始化断续器,间隔2svar ticker *time.Ticker = time.NewTicker(1 * time.Second)go func() {for t := range ticker.C {fmt.Println("Tick at", t)}}()time.Sleep(time.Second * 5)   //阻塞,则执行次数为sleep的休眠时间/ticker的时间ticker.Stop()     fmt.Println("Ticker stopped")
}
Tick at 2015-10-31 01:29:34.41859284 +0800 CST
Tick at 2015-10-31 01:29:35.420131668 +0800 CST
Tick at 2015-10-31 01:29:36.420565647 +0800 CST
Tick at 2015-10-31 01:29:37.421038416 +0800 CST
Tick at 2015-10-31 01:29:38.41944582 +0800 CST
Ticker stopped
示例二:使用channel控制停止ticker
package mainimport ("fmt""time"
)func main(){ //初始化断续器,间隔2svar ticker *time.Ticker = time.NewTicker(100 * time.Millisecond) //num为指定的执行次数num := 2c := make(chan int, num) go func() {for t := range ticker.C {c <- 1fmt.Println("Tick at", t)}}()time.Sleep(time.Millisecond * 1500)ticker.Stop()     fmt.Println("Ticker stopped")
}

go - time包的定时器/断续器相关推荐

  1. go time包定时器和断续器

    定时器 在time包中有两个函数可以帮助我们初始化time.Timer time.Newtimer函数 初始化一个到期时间据此时的间隔为3小时30分的定时器 t := time.Newtimer(3* ...

  2. Go 定时器和断续器

    1.定时器 Go语言中定时器可以实现在指定时间点执行特定的事件,定时器的实质是单向通道,time.Timer结构体类型中有一个time.Time类型的单向chan,具体声明如下: type Timer ...

  3. Golang停止ticker断续器

    1.原代码如下 package mainimport ("fmt""time" )func main() {intchan := make(chan int,1 ...

  4. golang并发编程-04-通道-02-定时器、断续器

    文章目录 1. 定时器 1.1 time.NewTimer 1.2 <-time.After() 1.3 停止 1.4 定时器重置 2 断续器 2.1 断续器使用 2.2 断续器中断 1. 定时 ...

  5. 介绍 Go 断续器(Tickers)

    介绍 Go 断续器(Tickers) 本文我们介绍 Go 断续器(Tickers)以及如何在应用中有效使用断续器.当我们需要在特定时间间隔内周期性重复执行动作,我们可以使用断续器.与协程一起使用可以实 ...

  6. 中国真空断续器市场现状研究分析与发展前景预测报告(2022)

    [报告篇幅]:109 [报告图表数]:150 [报告出版时间]:2021年12月 报告摘要 2021年中国真空断续器市场销售收入达到了 万元,预计2028年可以达到 万元,2022-2028期间年复合 ...

  7. PackageManagerService启动详解(五)之Android包信息体和解析器(中)

        PKMS启动详解(五)之Android包信息体和包解析器(中) Android PackageManagerService系列博客目录: PKMS启动详解系列博客概要 PKMS启动详解(一)之 ...

  8. (一)串口通信:同步通信与异步通信的区别;异步通信:握手、收发过程、心跳包、定时器、粘包、拆包、丢包、误包(或误码)、帧结构、奇偶校验、CRC校验等等

    目录 第一章.简介 第二章.并行通信 第三章.串行通信 3.1.同步通信 3.1.1.同步通信的原理 3.1.2.同步通信的数据格式 3.1.3.同步通信特点 3.2.异步通信 3.2.1.异步通信的 ...

  9. JavaScript的定时器延时器

    定时器 定义 按照设定的时间间隔 循环往复执行程序也就是 按照设定的时间间隔 每间隔设定的时间 执行一次程序事件间隔的单位是 毫秒也就是 按照间隔时间 一直重复执行程序 语法 setInterval( ...

最新文章

  1. MFC 加载并显示图片的四种方法
  2. oracle ebs form视频,ORACLE EBS FORM利用模板开发步骤
  3. 进入Windows的世界
  4. PAT A 1118. Birds in Forest (25)【并查集】
  5. 使用各类BeanUtils的时候,切记注意这个坑!
  6. Layui layer详细参数解释说明
  7. java中date类型如何赋值_Java 中的类型传递问题解惑
  8. 新东方预计6个月亏损超8亿美元
  9. 安卓拍照上传php服务器,Android拍照上传至PHP服务器并写入MySql数据库(下)
  10. mysql创建数据库sql语句_创建数据库的SQL语句:mysql数据库
  11. 尤大大(尤雨溪)的年度总结、预期
  12. PHPstrom + xdebug + postman断点调试代码 php谷歌浏览器代码断点调试
  13. 【ppt入门教程】Win7系统怎样实现ppt双屏显示不同的内容
  14. PS | 工作区,工具栏不见了怎么办 -- 复位基本功能
  15. Web 安全工具篇:Burp Suite 使用指南
  16. 2019清华计算机考研名单,2019年清华大学硕士研究生拟录取名单公示(清华MBA,考生编号排序)...
  17. 2018.1.28 牛客网2018年全国多校算法寒假训练营练习比赛题解
  18. 哪些数字适合作为域名主体?
  19. Linux系统安装中文字体
  20. 国内服务器证书,中国互联网协会-CNNIC推出国内首个服务器域名证书

热门文章

  1. php mysql抽奖转盘_thinkphp 微信抽奖源码PHP前后台+转盘+数据库完整示例
  2. ggplot2-设置坐标轴
  3. C语言利用ASCII码表统计字符串每个字符出现的次数
  4. windows使用ssh连接远程服务器
  5. 基于LM334芯片的恒流源调试
  6. 如何理解一台服务器可以绑定多个ip,一个ip可以绑定多个域名
  7. Android基础控件—SearchView
  8. 数学通道的应用(十五)-电阻的测量
  9. java 数字补零_java数字位数不足在前后补0
  10. Simulink模块字体设置