• [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)
    	}
    }
    
    

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

  • 相关阅读:
    单元测试之NUnit
    “Oracle.DataAccess.Client.OracleConnection”的类型初始值设定项引发异常
    功能强大的树状结构TreeGrid
    右键效果图
    可视化定义工作流(正在努力做......w)
    关于自动发送邮件换行等问题解决
    清空Cache
    .net发生类型为 System.OutOfMemoryException 的异常解决办法
    再谈xml
    Delphi日期函数大全
  • 原文地址:https://www.cnblogs.com/liujunhang/p/12538425.html
Copyright © 2020-2023  润新知