[golang]定时器

Posted liujunhang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[golang]定时器相关的知识,希望对你有一定的参考价值。

定时器

go中time包中定时器主要有三种,Sleep、Timer、Ticker。下面逐一来进行说明。

1: Sleep

可以通过Sleep进行指定时间的睡眠。

func Sleep(d Duration)

例如延迟三秒中后输出hello,world。

time.Sleep(time.Second * 3)
fmt.Println("hello,world")

2:Timer

Timer是一个定时器,代表未来的一个单一事件,你可以告诉timer你要等待多长时间。

type Timer struct {
   C <-chan Time
   r runtimeTimer
}

它提供一个channel,在定时时间到达之前,没有数据写入timer.C会一直阻塞。直到定时时间到,向channel写入值,阻塞解除,可以从中读取数据。

package main

import (
    "fmt"
    "time"
)

func main() {
    // 创建一个定时器
    timer1 := time.NewTimer(time.Second * 3) // 当三秒后定时器会向自己的c字节发送一个time.Time类型的元素值
    fmt.Println("现在的时间:",time.Now())


    t := <- timer1.C
    fmt.Println("接收到的时间:",t)
}

输出的结果:

现在的时间: 2020-03-21 10:30:22.064938 +0800 CST m=+0.000127008
接收到的时间: 2020-03-21 10:30:25.069487 +0800 CST m=+3.004669121

Process finished with exit code 0

如果只是单纯的想要睡眠延迟,建议使用time.Sleep()。

在其中,还有一个time.After()函数,作用是指定时间之后向返回的chan中写入时间。

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

从上面的源码中可以看出,time.After()是通过NewTimer实现。如果想要让效率更高一点,可以使用NewTimer。

示例:

t := time.After(time.Second*2)

fmt.Println(<-t) // 会在2秒钟之后得到结果

通常来说,可以通过select 和 time.Affer的结合,实现超时控制。

package main

import (
    "time"
    "fmt"
)

func main() {
    ch := make(chan string)

    go func() {
        time.Sleep(time.Second * 2)

        ch <- "result"
    }()

    select {
    case res := <-ch:
        fmt.Println(res)
    case <-time.After(time.Second * 1):
        fmt.Println("timeout")
    }
}

定时器整理:

  • 实现延迟功能。

    • <-time.After(2 * time.Second) // 定时2s,阻塞2s,2s后产生一个事件,往channel写内容
    • time.Sleep(2 * time.Second) // 睡眠延迟2秒
    • timer := time.NewTimer(2 * time.Second) // 延迟两秒 写入时间
      <- timer.C
  • 停止定时器

    • timer := time.NewTimer(3 * time.Second)
      go func() {
        <-timer.C
        fmt.Println("子协程可以打印了,因为定时器的时间到")
      }()
      timer.Stop() //停止定时器
      
      for {
        ;
      }
  • 定时器重置

    • timer := time.NewTimer(3 * time.Second)
      ok := timer.Reset(1 * time.Second) //重新设置为1s
      fmt.Println("ok = ", ok)
      <-timer.C
      fmt.Println("时间到")

3: Ticker

Ticker是一个周期触发定时的计时器,它会按照一个时间间隔往channel发送系统当前时间,而channel的接收者可以以固定的时间间隔从channel中读取事件。

type Ticker struct {
  C <-chan Time     // The channel on which the ticks are delivered.
  r runtimeTimer
}

例如:

package main

import (
    "fmt"
    "time"
)

func main() {
    // 创建一个周期定时ticker
    ticker := time.NewTicker(time.Second * 3)


    for {
        t := <-ticker.C

        fmt.Println(t)
    }
}

上面的代码中,每隔三秒就能获取一个时间。

以上是关于[golang]定时器的主要内容,如果未能解决你的问题,请参考以下文章

代码片段 - Golang 实现简单的 Web 服务器

代码片段 - Golang 实现集合操作

Golang:定时器的终止与重置

Golang中使用heap编写一个简单高效的定时器模块

json [Golang] golang #golang #snippets中有用的片段

golang 实现定时任务