你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

go time.Ticker的使用

2021/12/27 21:48:03

一篇速记

1. time.Ticker的正确使用方法

copy from go example

func main() {
  
    // Calling NewTicker method
    Ticker := time.NewTicker(2 * time.Second)
  
    // Creating channel using make
    // keyword
    mychannel := make(chan bool)
  
    // Go function
    go func() {
  
        // Using for loop
        for {
  
            // Select statement
            select {
  
            // Case statement
            case <-mychannel:
                return
  
            // Case to print current time
            case tm := <-Ticker.C:
                fmt.Println("The Current time is: ", tm)
            }
        }
    }()
  
    // Calling Sleep() method
    time.Sleep(7 * time.Second)
  
    // Calling Stop() method
    Ticker.Stop()
  
    // Setting the value of channel
    mychannel <- true
  
    // Printed when the ticker is turned off
    fmt.Println("Ticker is turned off!")
}

需要注意的一个事情是,ticker.stop不会关闭channel,只是保证不会向channel中发送新的数据而已,因此需要额外使用一个channel来显式地通知routine退出。

2. 为什么要如此设计

主要原因来自go中读取channel的语义,向一个已经关闭的channel写会导致panic,但是向一个已经关闭且没有值的channel会返回零值。因此如果stop函数语义中添加关闭channel的语义有可能给已有的应用造成问题(应用需要增加显式地判断channel返回值是否为零值的逻辑)。
引自github上的一个issue:

This came up once before and we decided not to do this. The problem is that closing the channel makes any pending receive unblock and deliver a zero value, which could cause significant confusion in existing code. In general channels do not have to be closed (they are not like file descriptors), and there is no real reason to close this one. In particular there are no range loops involved.