博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
golang中的 timer and ticker
阅读量:3988 次
发布时间:2019-05-24

本文共 2610 字,大约阅读时间需要 8 分钟。

睡眠

var d = 5*time.Secondtime.Sleep(d)

定时器 timer

func NewTimer(d Duration) *Timer {
c := make(chan Time, 1) t := &Timer{
C: c, r: runtimeTimer{
when: when(d), f: sendTime, arg: c, }, } startTimer(&t.r) return t}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: }}

timer 的运行机制是,当达到结束时间了,就会调用 f 函数,也就是 sendTime 函数,此函数会向 c 通道中写入当前时间,此函数的实现可以看出它并不保证一定会写入成功,只有当 timer.C 正在被读取时才会写入成功。

所以使用 timer 时你需要读取 timer.C 通道。

tr := time.NewTimer(d)fmt.Println(<-tr.C)

提前终止定时器

func (t *Timer) Stop() bool

重新设置定时器

func (t *Timer) Reset(d Duration) bool

timer 的应用:超时控制

func After(d Duration) <-chan Time {
return NewTimer(d).C}

After的使用:

c := time.After(d)ti := <-cfmt.Println(ti)

After实现超时控制

ch1 := make(chan int)go func() {
time.Sleep(10 * time.Second) ch1 <- 1}()select {
case <-ch1: fmt.Println("get msg")case <-time.After(d): fmt.Println("timeout")}

这是一种同步阻塞的方式来实现的超时控制。

还有一种异步的方式来控制超时。

ch1 := make(chan int)ch2 := make(chan int)time.AfterFunc(d, func() {
ch2<-1})go func() {
time.Sleep(10 * time.Second) ch1 <- 1}()select {
case <-ch1: fmt.Println("get msg")case <-ch2: fmt.Println("timeout")}

来看看 AfterFunc 的实现:

// AfterFunc waits for the duration to elapse and then calls f// in its own goroutine. It returns a Timer that can// be used to cancel the call using its Stop method.func AfterFunc(d Duration, f func()) *Timer {
t := &Timer{
r: runtimeTimer{
when: when(d), f: goFunc, arg: f, }, } startTimer(&t.r) return t}func goFunc(arg interface{
}, seq uintptr) {
go arg.(func())()}

时间结束后会开启一个 goroutine 来运行 f 函数。

context包中的WithTimeout()就是使用的AfterFunc。

循环定时器 ticker

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}

也是使用的通道来实现的通知。

for c := range time.NewTicker(d).C {
fmt.Println(c)}// 或者for c := range time.Tick(d) {
fmt.Println(c)}

带条件终止ticker

tick := time.NewTicker(d)n := 1for c := range tick.C {
fmt.Println(c) if n >= 3 {
tick.Stop() return } n++}

转载地址:http://tnaui.baihongyu.com/

你可能感兴趣的文章
ResourceBundle来读取配置文件及路径问题
查看>>
ibatis 与 sql 的问题
查看>>
onclick="return checkForm()" 、onclick="checkForm();return false;"解析 与 return false;
查看>>
List去重与equals/hashcode
查看>>
Websphere 学习(一)
查看>>
No enclosing instance of type XXX is accessible.
查看>>
Websphere 学习(二)
查看>>
Websphere 学习笔记(三)
查看>>
启动第二个eclipse报错
查看>>
修改jar源码
查看>>
Webshpere中数据库连接池中的连接没有正常释放
查看>>
quartz笔记(1)
查看>>
排序算法(1)-冒泡排序,选择排序,插入排序,希尔排序,快速排序
查看>>
[书]java8函数式编程(1)
查看>>
Junit initializationerror错误
查看>>
java中的Arrays.asList()浅析
查看>>
DbVisualizer 9 解决中文乱码问题(win7,win10)
查看>>
junit.framework.Assert 与org.junit.Assert
查看>>
git : error setting certificate verify locations
查看>>
二分查找的时间复杂度(TODO )
查看>>