[Golang]-7 定时器和打点器
我们常常需要在未来某个时刻运行 Go 代码,或者在某段时间间隔内重复运行。
Go 的内置 定时器 和 打点器 特性让这些很容易实现。
定时器
type Timer struct {
C <-chan Time
r runtimeTimer
}
通过 time.NewTimer() 创建,这种类型,timer只会执行一次,当然,可以在执行完以后通过调用 timer.Reset() 让定时器再次工作,并可以更改时间间隔。
例子1:
import (
"fmt"
"time"
)
func main() {
// 定时器表示在未来某一时刻的独立事件。
// 你告诉定时器需要等待的时间,然后它将提供一个用于通知的通道。这里的定时器将等待 2 秒。
timer1 := time.NewTimer(time.Second * 2)
// <-timer1.C 直到这个定时器的通道 C 明确的发送了定时器失效的值之前,将一直阻塞。
<-timer1.C
fmt.Println("Timer 1 expired")
// 如果你需要的仅仅是单纯的等待,你需要使用 time.Sleep。
// 定时器是有用原因之一就是你可以在定时器失效之前,取消这个定时器。这是一个例子
timer2 := time.NewTimer(time.Second)
go func() {
<-timer2.C
fmt.Println("Timer 2 expired")
}()
stop2 := timer2.Stop()
if stop2 {
fmt.Println("Timer 2 stopped")
}
}
输出:
imer 1 expired
Timer 2 stopped
说明:第一个定时器将在程序开始后 ~2s 失效,但是第二个在它没失效之前就停止了。
例子2:
func main() {
ch := make(chan int)
// timer 只能按时触发一次,可通过Reset()重置后继续触发。
timer := time.NewTimer(time.Second * 1)
go func() {
var x int
for {
select {
case <-timer.C:
x++
fmt.Printf("%d,%s\n", x, time.Now().Format("2006-01-02 15:04:05"))
if x < 10 {
timer.Reset(time.Second * 1)
} else {
ch <- x
}
}
}
}()
fmt.Println(<-ch)
}
输出
1,2020-12-17 09:12:42
2,2020-12-17 09:12:43
3,2020-12-17 09:12:44
4,2020-12-17 09:12:45
5,2020-12-17 09:12:46
6,2020-12-17 09:12:47
7,2020-12-17 09:12:48
8,2020-12-17 09:12:49
9,2020-12-17 09:12:50
10,2020-12-17 09:12:51
10
打点器
定时器 是当你想要在未来某一刻执行一次时使用的
打点器 则是当你想要在固定的时间间隔重复执行准备的。这里是一个打点器的例子,它将定时的执行,直到我们将它停止。
type Ticker struct {
C <-chan Time // The channel on which the ticks are delivered.
r runtimeTimer
}
例子1:
func main() {
// 打点器和定时器的机制有点相似:一个通道用来发送数据。
// 这里我们在这个通道上使用内置的 range 来迭代值每隔500ms 发送一次的值。
ticker := time.NewTicker(time.Millisecond * 500)
go func() {
for t := range ticker.C {
fmt.Println("Tick at", t)
}
}()
// 打点器可以和定时器一样被停止。一旦一个打点停止了,将不能再从它的通道中接收到值。我们将在运行后 1600ms停止这个打点器。
time.Sleep(time.Millisecond * 1600)
ticker.Stop()
fmt.Println("Ticker stopped")
}
输出:
Tick at 2020-12-17 09:16:10.9695842 +0800 CST m=+0.505906801
Tick at 2020-12-17 09:16:11.4687539 +0800 CST m=+1.005076501
Tick at 2020-12-17 09:16:11.9687398 +0800 CST m=+1.505062401
Ticker stopped
当我们运行这个程序时,这个打点器会在我们停止它前打点3次。
例子2:
func main() {
// 打点器和定时器的机制有点相似:使用一个通道用来发送数据。
ticker := time.NewTicker(time.Second * 1) // 运行时长
ch := make(chan int)
go func() {
var x int
for x < 10 {
select {
case <-ticker.C:
x++
fmt.Printf("%d\n", x)
}
}
ticker.Stop()
ch <- 0
}()
// 通过通道阻塞,让任务可以执行完指定的次数。
<-ch
}
输出:
1
2
3
4
5
6
7
8
9
10
该ticker每1秒触发一次,即ticker.C中每一秒会有一个内容加入,最后通过向ch中写入数字,让程序解除阻塞,继续执行。
After()方法
例子:
func main() {
// 阻塞一下,等待主进程结束
tt := time.NewTimer(time.Second * 5)
<-tt.C
fmt.Println("over.")
<-time.After(time.Second * 3)
fmt.Println("再等待3秒退出。tt 没有终止,打印出 over 后会看见在继续执行...")
tt.Stop()
<-time.After(time.Second * 1)
fmt.Println("tt.Stop()后, tt 仍继续执行,只是关闭了 tt.C 通道。")
}
输出
over.
再等待3秒退出。tt 没有终止,打印出 over 后会看见在继续执行...
tt.Stop()后, tt 仍继续执行,只是关闭了 tt.C 通道。
[Golang]-7 定时器和打点器的更多相关文章
- go语言从例子开始之Example32.打点器
定时器 是当你想要在未来某一刻执行一次时使用的 - 打点器 则是当你想要在固定的时间间隔重复执行准备的.这里是一个打点器的例子,它将定时的执行,直到我们将它停止. Example: package m ...
- Unity中的定时器与延时器
JavaScript中的定时器与延时器,分别是 setInterval.setTimeout,对应的清理函数是:clearInterval.clearTimeout. 而在Unity中,则分别是:In ...
- js课程 3-9 js内置对象定时器和超时器怎么使用
js课程 3-9 js内置对象定时器和超时器怎么使用 一.总结 一句话总结:定时器: 1.定义 sobj=setInterval(func,1000); 2.清除 cl ...
- 033_go语言中的打点器
代码演示 package main import "fmt" import "time" func main() { ticker := time.NewTic ...
- springMVC + quartz实现定时器(任务调度器)
首先我们要知道任务调度器(定时器)有几种,这边我会写三种 第一种是基于JDK的本身的一个定时器(优点:简单,缺点:满足不了复杂的需求) package com.timer1; import java. ...
- Golang之定时器,recover
滴答滴答……定时器的使用 package main import ( "fmt" "time" ) //定时器的使用 func main() { t := ti ...
- 生产者消费者模式做一个golang的定时器
在主程序启动的时候开一个goroutine作为消费者,用管道连接生产者和消费者,消费者处于无限循环,从管道中获取channel传过来定时event 注意:channel在消费者创建的时候就连通生产者和 ...
- STM32 HAL库学习系列第5篇 定时器TIM---编码器接口模式配置
cube基本配置,外设开启编码器,串口2 可能大家在设置的时候有这个错误 错误:error: #20: identifier "TIM_ICPOLARITY_BOTHEDGE" ...
- golang的定时器NewTimer、NewTicker使用
package main import ( "fmt" "sync" "time" ) /** *ticker只要定义完成,从此刻开始计时, ...
随机推荐
- 【ORA】ORA-39002,ORA-39070,ORA-29283, ORA-06512,ORA-29283解决办法
今天使用IMPDP导入的时候报了一个错误 ORA-39002: invalid operation ORA-39070: Unable to open the log file. ORA-2928 ...
- 【Oracle】regexp_substr()函数详解
环境:Oracle10.2.0.5 在SQL中尝试使用正则 可以试下regexp_substr()来进行分割 首先创建一个实验视图: SQL> create or replace view te ...
- 基础练习(上) - 蓝桥杯(Python实现)
闰年判断: 题目: 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 给定一个年份,判断这一年是不是闰年. 当以下情况之一满足时,这一年是闰年: 1. 年份是4的倍数而不是100的倍数 ...
- ctfhub技能树—信息泄露—git泄露—Log
什么是git泄露? 当前大量开发人员使用git进行版本控制,对站点自动部署.如果配置不当,可能会将.git文件夹直接部署到线上环境.这就引起了git泄露漏洞. 打开靶机环境 查看网页内容 使用dirs ...
- VKM5对应的BAPI或者函数
在业务上,当一个交货单创建后,可能需要使用事物VKM5进行批准(解冻)才能做后续的捡配,发货过账等操作,通过搜索引擎发现,很多人也都会问是否有对应的bapi或者函数,替代VKM5,能够自开发程序进行批 ...
- HTML基础复习4
CSS的应用 模块的边框 设置边框样式 border-style::如果是一个值那么表示四个边的样式都一样:如果是两个值那么第一个值代表上下,第二个值代表左右:如果是三个值,第一个值代表上,第二个值代 ...
- 事件循环Event loop到底是什么
摘要:本文通过结合官方文档MDN和其他博客深入解析浏览器的事件循环机制,而NodeJS有另一套事件循环机制,不在本文讨论范围中.process.nextTick和setImmediate是NodeJS ...
- windows2012-2016亲测安装mysql8.0
先去官网下载点击的MySQL的下载 下载完成后解压 解压完是这个样子 不要手动创建Data文件夹和my.ini文件, cmd命令窗口进入bin目录,如果已经做了环境变量那随意在哪里打开. mysqld ...
- WPF入门学习(转)
WPF基础知识 总结的学习WPF的几点基础知识: 1) C#基础语法知识(或者其他.NET支持的语言):这个是当然的了,虽然WPF是XAML配置的,但是总还是要写代码的,相信各位读者应该也都有这个基础 ...
- virtualenv安装和配置
安装命令 命令执行结束 配 执行命令:virtualenv testvir 执行完成:会在当前目录下生成如下文件夹 进入到testvir目录 进入Scripts目录: 进入虚拟环境:执行 activa ...