前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >转-- Golang中timer定时器实现原理

转-- Golang中timer定时器实现原理

作者头像
李海彬
发布2018-03-21 10:10:10
2K0
发布2018-03-21 10:10:10
举报
文章被收录于专栏:Golang语言社区

一般我们导入import ("time")包,然后调用time.NewTicker(1 * time.Second) 实现一个定时器:

代码语言:javascript
复制
func timer1() {

        timer1 := time.NewTicker(1 * time.Second)

        for {

                select {

                case <-timer1.C:

                        xxx() //执行我们想要的操作

                }

        }

}

再看看timer包中NewTicker的具体实现:

代码语言:javascript
复制
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如下:

代码语言:javascript
复制
type Ticker struct {

        C <-chan Time // The channel on which the ticks are delivered.

        r runtimeTimer

}

Ticker中的C为数据类型为Time的单向管道,只能读,不能写

再分下一下runtimeTimer的参数:

代码语言:javascript
复制
r: runtimeTimer{

                        when:   when(d),

                        period: int64(d),

                        f:      sendTime,

                        arg:    c,

                }

其中sendTime为回调函数,startTimer时候注册的,arg为回调函数需要的参数arg

  1. startTimer(&t.r)

再进一步看看startTimer的实现:

代码语言:javascript
复制
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函数,实现定时执行某些事件的功能:

代码语言:javascript
复制
for {

    select {

        case <-timer1.C:

          xxxx()

     }

   }
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-04-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档