我们常常需要在未来某个时刻运行 Go 代码,或者在某段时间间隔内重复运行。

Go 的内置 定时器 和 打点器 特性让这些很容易实现。

定时器

  1. type Timer struct {
  2. C <-chan Time
  3. r runtimeTimer
  4. }

通过 time.NewTimer() 创建,这种类型,timer只会执行一次,当然,可以在执行完以后通过调用 timer.Reset() 让定时器再次工作,并可以更改时间间隔。

例子1:

  1. import (
  2. "fmt"
  3. "time"
  4. )
  5. func main() {
  6. // 定时器表示在未来某一时刻的独立事件。
  7. // 你告诉定时器需要等待的时间,然后它将提供一个用于通知的通道。这里的定时器将等待 2 秒。
  8. timer1 := time.NewTimer(time.Second * 2)
  9. // <-timer1.C 直到这个定时器的通道 C 明确的发送了定时器失效的值之前,将一直阻塞。
  10. <-timer1.C
  11. fmt.Println("Timer 1 expired")
  12. // 如果你需要的仅仅是单纯的等待,你需要使用 time.Sleep。
  13. // 定时器是有用原因之一就是你可以在定时器失效之前,取消这个定时器。这是一个例子
  14. timer2 := time.NewTimer(time.Second)
  15. go func() {
  16. <-timer2.C
  17. fmt.Println("Timer 2 expired")
  18. }()
  19. stop2 := timer2.Stop()
  20. if stop2 {
  21. fmt.Println("Timer 2 stopped")
  22. }
  23. }

输出:

  1. imer 1 expired
  2. Timer 2 stopped

说明:第一个定时器将在程序开始后 ~2s 失效,但是第二个在它没失效之前就停止了。

例子2:

  1. func main() {
  2. ch := make(chan int)
  3. // timer 只能按时触发一次,可通过Reset()重置后继续触发。
  4. timer := time.NewTimer(time.Second * 1)
  5. go func() {
  6. var x int
  7. for {
  8. select {
  9. case <-timer.C:
  10. x++
  11. fmt.Printf("%d,%s\n", x, time.Now().Format("2006-01-02 15:04:05"))
  12. if x < 10 {
  13. timer.Reset(time.Second * 1)
  14. } else {
  15. ch <- x
  16. }
  17. }
  18. }
  19. }()
  20. fmt.Println(<-ch)
  21. }

输出

  1. 1,2020-12-17 09:12:42
  2. 2,2020-12-17 09:12:43
  3. 3,2020-12-17 09:12:44
  4. 4,2020-12-17 09:12:45
  5. 5,2020-12-17 09:12:46
  6. 6,2020-12-17 09:12:47
  7. 7,2020-12-17 09:12:48
  8. 8,2020-12-17 09:12:49
  9. 9,2020-12-17 09:12:50
  10. 10,2020-12-17 09:12:51
  11. 10

打点器

定时器 是当你想要在未来某一刻执行一次时使用的

打点器 则是当你想要在固定的时间间隔重复执行准备的。这里是一个打点器的例子,它将定时的执行,直到我们将它停止。

  1. type Ticker struct {
  2. C <-chan Time // The channel on which the ticks are delivered.
  3. r runtimeTimer
  4. }

例子1:

  1. func main() {
  2. // 打点器和定时器的机制有点相似:一个通道用来发送数据。
  3. // 这里我们在这个通道上使用内置的 range 来迭代值每隔500ms 发送一次的值。
  4. ticker := time.NewTicker(time.Millisecond * 500)
  5. go func() {
  6. for t := range ticker.C {
  7. fmt.Println("Tick at", t)
  8. }
  9. }()
  10. // 打点器可以和定时器一样被停止。一旦一个打点停止了,将不能再从它的通道中接收到值。我们将在运行后 1600ms停止这个打点器。
  11. time.Sleep(time.Millisecond * 1600)
  12. ticker.Stop()
  13. fmt.Println("Ticker stopped")
  14. }

输出:

  1. Tick at 2020-12-17 09:16:10.9695842 +0800 CST m=+0.505906801
  2. Tick at 2020-12-17 09:16:11.4687539 +0800 CST m=+1.005076501
  3. Tick at 2020-12-17 09:16:11.9687398 +0800 CST m=+1.505062401
  4. Ticker stopped

当我们运行这个程序时,这个打点器会在我们停止它前打点3次。

例子2:

  1. func main() {
  2. // 打点器和定时器的机制有点相似:使用一个通道用来发送数据。
  3. ticker := time.NewTicker(time.Second * 1) // 运行时长
  4. ch := make(chan int)
  5. go func() {
  6. var x int
  7. for x < 10 {
  8. select {
  9. case <-ticker.C:
  10. x++
  11. fmt.Printf("%d\n", x)
  12. }
  13. }
  14. ticker.Stop()
  15. ch <- 0
  16. }()
  17. // 通过通道阻塞,让任务可以执行完指定的次数。
  18. <-ch
  19. }

输出:

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10

该ticker每1秒触发一次,即ticker.C中每一秒会有一个内容加入,最后通过向ch中写入数字,让程序解除阻塞,继续执行。

After()方法

例子:

  1. func main() {
  2. // 阻塞一下,等待主进程结束
  3. tt := time.NewTimer(time.Second * 5)
  4. <-tt.C
  5. fmt.Println("over.")
  6. <-time.After(time.Second * 3)
  7. fmt.Println("再等待3秒退出。tt 没有终止,打印出 over 后会看见在继续执行...")
  8. tt.Stop()
  9. <-time.After(time.Second * 1)
  10. fmt.Println("tt.Stop()后, tt 仍继续执行,只是关闭了 tt.C 通道。")
  11. }

输出

  1. over.
  2. 再等待3秒退出。tt 没有终止,打印出 over 后会看见在继续执行...
  3. tt.Stop()后, tt 仍继续执行,只是关闭了 tt.C 通道。

[Golang]-7 定时器和打点器的更多相关文章

  1. go语言从例子开始之Example32.打点器

    定时器 是当你想要在未来某一刻执行一次时使用的 - 打点器 则是当你想要在固定的时间间隔重复执行准备的.这里是一个打点器的例子,它将定时的执行,直到我们将它停止. Example: package m ...

  2. Unity中的定时器与延时器

    JavaScript中的定时器与延时器,分别是 setInterval.setTimeout,对应的清理函数是:clearInterval.clearTimeout. 而在Unity中,则分别是:In ...

  3. js课程 3-9 js内置对象定时器和超时器怎么使用

    js课程 3-9 js内置对象定时器和超时器怎么使用 一.总结 一句话总结:定时器:    1.定义    sobj=setInterval(func,1000);        2.清除    cl ...

  4. 033_go语言中的打点器

    代码演示 package main import "fmt" import "time" func main() { ticker := time.NewTic ...

  5. springMVC + quartz实现定时器(任务调度器)

    首先我们要知道任务调度器(定时器)有几种,这边我会写三种 第一种是基于JDK的本身的一个定时器(优点:简单,缺点:满足不了复杂的需求) package com.timer1; import java. ...

  6. Golang之定时器,recover

    滴答滴答……定时器的使用 package main import ( "fmt" "time" ) //定时器的使用 func main() { t := ti ...

  7. 生产者消费者模式做一个golang的定时器

    在主程序启动的时候开一个goroutine作为消费者,用管道连接生产者和消费者,消费者处于无限循环,从管道中获取channel传过来定时event 注意:channel在消费者创建的时候就连通生产者和 ...

  8. STM32 HAL库学习系列第5篇 定时器TIM---编码器接口模式配置

    cube基本配置,外设开启编码器,串口2 可能大家在设置的时候有这个错误 错误:error:  #20: identifier "TIM_ICPOLARITY_BOTHEDGE" ...

  9. golang的定时器NewTimer、NewTicker使用

    package main import ( "fmt" "sync" "time" ) /** *ticker只要定义完成,从此刻开始计时, ...

随机推荐

  1. 【Linux】centos7中 root家目录中perl5文件夹无法删除问题解决

    由于新项目上线,安装了一些perl的一些包 但是发现,在/root下有一个perl5/的文件夹,删除后,重新登录又会出现,很是烦人,而且他还没有内容,就是一个空文件 那么着手搞掉他 环境:centos ...

  2. C++:I/O流的概念和流类库的结构

    一.C++输入输出包含以下三个方面的内容: 对系统指定的标准设备的输入和输出.即从键盘输入数据,输出到显示器屏幕.这种输入输出称为标准的输入输出,简称标准I/O. 以外存磁盘文件为对象进行输入和输出, ...

  3. 面向对象的延伸与Java内部定义类的应用

    识别类 传统的过程化程序设计,必须从顶部的main函数开始编写程序,在面向对象程序设计时没有所谓的"顶部".首先从设计类开始,然后再往每个类中添加方法. 识别类的规则是在分析问题的 ...

  4. USB充电限流IC,可调到4.8A,输入 6V关闭

    随着手机充电电流的提升,和设备的多样化,USB限流芯片就随着需求的增加而越来越多,同时为了更好的保护电子设备,需要进行一路或者多路的负载进行限流. 一般说明 PW1503,PW1502是超低RDS(O ...

  5. Redis-第五章节-8种数据类型

    目录 一.Redis对key的操作 二.五种数据类型 String类型 List(集合) Set(集合) Hash(哈希) Zset(有序集合) 三.三种特殊数据类型 geospatial(地理位置) ...

  6. Ajax中的同源政策

    Ajax中的同源政策 Ajax请求限制 Ajax只能向自己的服务器发送请求.比如现在有一个A网站.有一个B网站,A网站中的HTML文件只能向A网站服务器中发送Ajax请求,B网站中的HTML文件只能向 ...

  7. Manachar’s Algorithm

    Manachar's Algorithm Longest palindromic substring - Wikipedia  https://en.wikipedia.org/wiki/Longes ...

  8. BBR implements bbr-like limiter 限流

    pkg/ratelimit/bbr/bbr.go:68 github.com/go-kratos // BBR implements bbr-like limiter.// It is inspire ...

  9. Codeforces #698 (Div. 2) E. Nezzar and Binary String 题解

    中文题意: 给你两个长度为 \(n\) 的01串 \(s,f,\)有 \(q\) 次询问. 每次询问有区间 \([\ l,r\ ]\) ,如果 \([\ l,r\ ]\) 同时包含\(0\)和\(1\ ...

  10. 2021最新WordPress安装教程(一):Centos7安装Apache

    一转眼2020年已经过去了,看网络上很多WordPress的安装教程都比较旧,有些写的不太详细,WordPress是站长最喜欢的一款建站系统,数据统计到2020年为止,WordPress在所有网站的市 ...