golang的定时器

Golang的Timer类,是一个普遍意义上的定时器,它有着普通定时器的一些特性,例如:

给定一个到期时间,和一个回调函数,到期后会调用回调函数
重置定时器的超时时间
停止定时器
Golang的Timer在源码中,实现的方式是以一个小顶堆来维护所有的Timer集合。

package main

import (
    "fmt"
    "time"
)

func main() {

    aChan := make(chan int, 1)
    ticker := time.NewTicker(time.Second * 1)

    go func() {
        for {
            select {
            case <-ticker.C:
                fmt.Printf("ticked at %v\n", time.Now())
            }
        }

    }()
    //阻塞主线程
    <-aChan
}

关于定时器

定时器是开发的基本组件

以下这些摘自博客
https://www.ibm.com/developerworks/cn/linux/l-cn-timers/

定时器的基本模型

StartTimer(Interval, TimerId, ExpiryAction)
    注册一个时间间隔为 Interval 后执行 ExpiryAction 的定时器实例,其中,返回 TimerId 以区分在定时器系统中的其他定时器实例。

StopTimer(TimerId)
    根据 TimerId 找到注册的定时器实例并执行 Stop 。

PerTickBookkeeping()
    在一个 Tick 内,定时器系统需要执行的动作,它最主要的行为,就是检查定时器系统中,是否有定时器实例已经到期。注意,这里的 Tick 实际上已经隐含了一个时间粒度 (granularity) 的概念。

ExpiryProcessing()
    在定时器实例到期之后,执行预先注册好的 ExpiryAction 行为。

定时器分类

上面说了基本的定时器模型,但是针对实际的使用情况,又有以下 2 种基本行为的定时器:
Single-Shot Timer
    这种定时器,从注册到终止,仅仅只执行一次。
Repeating Timer
    这种定时器,在每次终止之后,会自动重新开始。
    本质上,可以认为 Repeating Timer 是在 Single-Shot Timer 终止之后,     再次注册到定时器系统里的 Single-Shot Timer,因此,
    在支持 Single-Shot Timer 的基础上支持 
    Repeating Timer 并不算特别的复杂。

实现方式

1 基于链表和信号实现定时器 
2 基于 2.6 版本内核定时器的实现 (Posix 实时定时器 )
3 最小堆实现的定时器
4 基于时间轮 (Timing-Wheel) 方式实现的定时器

这个很有意思

实现方式    StartTimer  StopTimer   PerTickBookkeeping
基于链表    O(1)    O(n)    O(n)
基于排序链表  O(n)    O(1)    O(1)
基于最小堆   O(lgn)  O(1)    O(1)
基于时间轮   O(1)    O(1)    O(1)

你可能感兴趣的:(goang)