在go自带的timer实现中,采用的是通常的最小堆的方式,具体可以参见这里

最小堆能够提供很好的定时精度,但是,在实际情况中,我们并不需要这样高精度的定时器,譬如对于一个连接,如果它在2分钟以内没有数据交互,我们就将其删除,2分钟并不需要那么精确,多几秒少几秒都无所谓的。

以前我们单独实现了一个timingwheel,采用的是channel close的方式来处理低精度,超大量timer定时的问题,详见这里

但是timingwheel只有After接口,远远不能满足实际的需求,于是我按照linux timer的实现方式,依葫芦画瓢,弄了一个go版本的实现。linux timer的实现,参考这篇

后续用go timer来表示我自己实现的timer。

在linux中,我们使用tick来表示一次中断的时间,用jiffies来表示系统自启动以来流逝的tick次数。在go timer中,我们在创建一个wheel的时候,需要指定一次tick的时间,如下:

func NewWheel(tick time.Duration) *Wheel

Wheel是go timer统一对timer进行管理的地方。对于每一次tick,我们采用go自带的ticker进行模拟。

为了便于外部使用,我仍然提供的是跟go自己timer一样的接口,譬如:

func NewTimer(d time.Duration) *Timer

在NewTimer中,参数d是一个time duration,我们还需要根据tick来进行换算,得到go timer中实际的expires,也就是在多少次jiffies后该timer触发。

譬如,NewTimer参数为10s,tick为1s,那么经过10个jiffies之后,该timer就会超时触发。如果tick为500ms,那么需要经过20个jiffies之后,该timer才会被触发。

所以timer超时jiffies的计算如下:

expires = wheel.jiffies + d / wheel.tick

详细的代码在https://github.com/siddontang/golib/tree/master/timer

golang:一个高性能低精度timer实现的更多相关文章

  1. 第三十三章 metrics(1) - graphite搭建 + whisper存储模式 + 高精度向低精度聚合方式 + 集成StatsD + 集成grafana

    组件介绍: carbon:Carbon实际上是一系列守护进程,组成一个Graphite安装的存储后端.这些守护进程用一个名为Twisted的事件驱动网络引擎监听时间序列数据.Twisted框架让Car ...

  2. int类型被强制转换成较低精度的byte类型

    公司的项目上线之前会进行代码合规性检查,其中很容易违反的一个规则就是“不要把原始类型转换成较低的精度”,实际开发的过程中,很多方法在处理数据时,尤其在做移位操作的时候,难免要把int类型转换成byte ...

  3. 用PHP打造一个高性能好用的网站

    用PHP打造一个高性能好用的网站 1. 说到高可用的话要提一下redis,用过的都知道redis是一个具备数据库特征的nosql,正好弥补了PHP的瓶颈,个人认为PHP的 瓶颈在于数据库,像Apach ...

  4. Si7006主要面向传统上使用的分立RH / T传感器的低精度的应用

    Silicon Labs的Si7006 / 13/20/21个I 2 C相对湿度及温度传感器结合充分工厂校准湿度和温度传感器元件与模拟-数字转换器,信号处理和一个I 2 C主机接口.专利使用业界标准低 ...

  5. 又一个高性能轻量级的iOS模型框架YYModel

    前言 iOS的模型框架其实有很多了,去年研究过Mantle,也了解过JSONModel.MJExtension,最近的项目项目优化的时候,再次考虑,基于轻量级.高性能的考虑,最终选择了YYModel. ...

  6. workerman是一个高性能的PHP socket服务器框架

    workerman-chatorkerman是一款纯PHP开发的开源高性能的PHP socket服务器框架.被广泛的用于手机app.手游服务端.网络游戏服务器.聊天室服务器.硬件通讯服务器.智能家居. ...

  7. 【Jetlang】一个高性能的Java线程库

    actor  Jetlang 提供了一个高性能的Java线程库,该库是 JDK 1.5 中的 java.util.concurrent 包的补充,可用于基于并发消息机制的应用. .net的MS CCR ...

  8. Tair是一个高性能,分布式,可扩展,高可靠的key/value结构存储系统(转)

    Tair是一个高性能,分布式,可扩展,高可靠的key/value结构存储系统! Tair专为小文件优化,并提供简单易用的接口(类似Map)Tair支持Java和C版本的客户端 Tair is a di ...

  9. 一个高性能、轻量级的分布式内存队列系统--beanstalk

    Beanstalk是一个高性能.轻量级的.分布式的.内存型的消息队列系统.最初设计的目的是想通过后台异步执行耗时的任务来降低高容量Web应用系统的页面访问延迟.其实Beanstalkd是典型的类Mem ...

随机推荐

  1. Java内存分配、管理小结

    转载自:http://java-mzd.iteye.com/blog/848635

  2. linux设置oracle自动启动

    用root用户 在/etc/init.d/目录下创建Oracle的服务文件 cd /etc/init.d vi oracle11g   添加内容如下   #!/bin/bash # chkconfig ...

  3. 给div添加2个class

    <div class='center nocontent'>  类名用空格分开 在优先级一样的情况下就近原则  优先级# 100 .10 <span>这种标签是1 所以的相加 ...

  4. 实践详细篇-Windows下使用VS2015编译的Caffe训练mnist数据集

    上一篇记录的是学习caffe前的环境准备以及如何创建好自己需要的caffe版本.这一篇记录的是如何使用编译好的caffe做训练mnist数据集,步骤编号延用上一篇 <实践详细篇-Windows下 ...

  5. IF判断条件说明

    在Python中,任何非零整数都为true,0是false:判断条件也可以是任何序列(列表.元组.字符串):所有长度不为零的为true,否则为false,比如:空序列为false.简而言之:非0非空为 ...

  6. Python中的转义

    在Python交互式解释器中,输出的字符串会用引号引起来,特殊字符会用反斜杠(\)转义.如果遇到带有\的字符被当作特殊字符时,有以下两种处理方法:1.使用双反斜杠(\\)来转义2.使用原始字符串,方法 ...

  7. Python3 错误和异常

    Python有两种错误很容易辨认:语法错误和异常. 语法错误 Python 的语法错误或者称之为解析错,是初学者经常碰到的,如下实例 >>> while True print('He ...

  8. WiFi文件上传框架SGWiFiUpload

    背景 在iOS端由于文件系统的封闭性,文件的上传变得十分麻烦,一个比较好的解决方案是通过局域网WiFi来传输文件并存储到沙盒中. 简介 SGWiFiUpload是一个基于CocoaHTTPServer ...

  9. OpenCV, MatBGR2ARGB, ARGB2MatBGR

    代码片段~ unsigned int* abMatBGR2ARGB(Mat imag) { int nCols; int nRows; unsigned int *pbuff = NULL; if(i ...

  10. maven项目管理

    systemPath方式 有些不通用的包,maven仓库没有,只能通过本地包依赖,就像下面方式: 在需要依赖的项目建lib文件夹,如下: 然后在pom.xml项目管理文件里面加入本地依赖,如下 这种情 ...