转-- Golang中timer定时器实现原理
时间:2022-05-05
本文章向大家介绍转-- Golang中timer定时器实现原理,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
一般我们导入import ("time")包,然后调用time.NewTicker(1 * time.Second) 实现一个定时器:
func timer1() {
timer1 := time.NewTicker(1 * time.Second)
for {
select {
case <-timer1.C:
xxx() //执行我们想要的操作
}
}
}
再看看timer包中NewTicker的具体实现:
func NewTicker(d Duration) *Ticker {
if d <= 0 {
panic(errors.New("non-positive interval for NewTicker"))
}
// Give the channel a 1-element time buffer.
// If the client falls behind while reading, we drop ticks
// on the floor until the client catches up.
c := make(chan Time, 1)
t := &Ticker{
C: c,
r: runtimeTimer{
when: when(d),
period: int64(d),
f: sendTime,
arg: c,
},
}
startTimer(&t.r)
return t
}
其中Ticker的具体struct如下:
type Ticker struct {
C <-chan Time // The channel on which the ticks are delivered.
r runtimeTimer
}
Ticker中的C为数据类型为Time的单向管道,只能读,不能写
再分下一下runtimeTimer的参数:
r: runtimeTimer{
when: when(d),
period: int64(d),
f: sendTime,
arg: c,
}
其中sendTime为回调函数,startTimer时候注册的,arg为回调函数需要的参数arg
- startTimer(&t.r)
再进一步看看startTimer的实现:
func sendTime(c interface{}, seq uintptr) {
// Non-blocking send of time on c.
// Used in NewTimer, it cannot block anyway (buffer).
// Used in NewTicker, dropping sends on the floor is
// the desired behavior when the reader gets behind,
// because the sends are periodic.
select {
case c.(chan Time) <- Now():
default:
}
}
通过往管道里面写时间,注意我们Ticker结构里面的C是单向管道,只能读不能写,那要怎么写数据了
通过类型转化,因为channel是一个原生类型,因此不仅支持被传递,还支持类型转换,装换成双向的管道channel,往里面
写数据,用户API那边提供的是单向管道,用户只能就只能读数据,就相当于一层限制
最后,调用执行具体xxx函数,实现定时执行某些事件的功能:
for {
select {
case <-timer1.C:
xxxx()
}
}
- php dirname(__FILE__) 获取当前文件的绝对路径
- 洛谷P2939 [USACO09FEB]改造路Revamping Trails(最短路)
- 微信公众平台开发接口PHP SDK完整版
- 我的HTML总结之HTML发展史
- BZOJ 4152: [AMPPZ2014]The Captain(最短路)
- js获取div编辑框,textarea,input text的光标位置,兼容FF和IE
- BZOJ 4289: PA2012 Tax(最短路)
- php QR Code二维码生成类
- BZOJ 3714: [PA2014]Kuglarz(最小生成树)
- 我的HTML总结之表单
- php 二维码生成类
- HDU 2516 取石子游戏(斐波那契博弈)
- angularjs MVC、模块化、依赖注入详解
- BZOJ 2940: [Poi2000]条纹(Multi-Nim)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- MySQL优化--概述以及索引优化分析
- MySQL优化--查询分析工具以及各种锁
- MySQL优化--MVCC
- Linux入门--基础命令
- Linux入门--权限管理、任务调度、磁盘管理
- 【Rust日报】2020-08-05 -- 如何在2020年进一步加快 Rust 编译器的速度
- Linux学习--网络、进程、服务、软件管理
- IOS label 设置行高
- 重学数据结构(序:概览)
- 【Rust日报】2020-08-06 使用 Rust 编写的 Lambdas 在 AWS IoT 和 SQS 队列之间传递消息
- react-router-config的使用
- Spring 源码解读第七弹!bean 标签的解析
- Kubeflow实战: 入门介绍与部署实践
- matplotlib基础绘图命令之violinplot
- 性能分析(3)- 短时进程导致用户 CPU 使用率过高案例