timer
There are two functions in the time package that can help us initialize time.Timer
time.Newtimer function
Initialize a timer that expires at an interval of 3 hours and 30 minutes
t := time.Newtimer(3*time.Hour + 30*time.Minute)
Note that the variable t here is of type *time.NewTimer, and the collection of methods of this pointer type contains two methods
- Rest
For resetting the timer
This method returns a bool-type value - Stop
To stop the timer
The method returns a bool-type value that, if false, indicates that the timer has expired or stopped before, and vice versa, returns true.
The timer field C lets us know in time that the event that the timer expires is coming. C is a chan time.Time type buffer channel. Once the expiration time is touched, the timer sends its own C field an element value of type time.Time
Example 1: A simple timer
package main import ( "fmt" "time" ) func main(){ //Initialization timer t := time.NewTimer(2 * time.Second) //current time now := time.Now() fmt.Printf("Now time : %v.\n", now) expire := <- t.C fmt.Printf("Expiration time: %v.\n", expire) }
Now time : 2015-10-31 01:19:07.210771347 +0800 CST. Expiration time: 2015-10-31 01:19:09.215489592 +0800 CST.
Example 2: The simple timeout we did before the transformation
package main import ( "fmt" "time" ) func main(){ //Initialize Channel ch11 := make(chan int, 1000) sign := make(chan byte, 1) //Write data to ch11 channel for i := 0; i < 1000; i++ { ch11 <- i } //select from a single Goroutine go func(){ var e int ok := true //First declare a value of type *time.Timer, then reuse it as much as possible in anonymous functions declared after the associated case var timer *time.Timer for{ select { case e = <- ch11: fmt.Printf("ch11 -> %d\n",e) case <- func() <-chan time.Time { if timer == nil{ //Initialize a timer with an expiration time of 1 ms timer = time.NewTimer(time.Millisecond) }else { //Reuse, reset timer by Reset method timer.Reset(time.Millisecond) } //Return the result when you know the timer expiration event is coming return timer.C }(): fmt.Println("Timeout.") ok = false break } //End for loop if !ok { sign <- 0 break } } }() //Used technique to read sign channel data in order to wait for Goroutine to select to execute. <- sign }
time.After function
The time.After function, which indicates how long after, but does not block until the channel content is removed, and subsequent programs can continue executing
Because of the After feature, it is often used to handle timeout problems
package main import ( "fmt" "time" ) func main(){ ch1 := make(chan int, 1) ch2 := make(chan int, 1) select { case e1 := <-ch1: //If the ch1 channel successfully reads data, execute the case processing statement fmt.Printf("1th case is selected. e1=%v",e1) case e2 := <-ch2: //If the ch2 channel successfully reads the data, execute the case processing statement fmt.Printf("2th case is selected. e2=%v",e2) case <- time.After(2 * time.Second): fmt.Println("Timed out") } }
time.Sleep function
Indicates how long to sleep, is blocked while hibernating, and subsequent programs cannot be executed.
time.Afterfunc function
Example 3: Custom timer
package main import ( "fmt" "time" ) func main(){ var t *time.Timer f := func(){ fmt.Printf("Expiration time : %v.\n", time.Now()) fmt.Printf("C`s len: %d\n", len(t.C)) } t = time.AfterFunc(1*time.Second, f) //Sleep the current Goroutine for 2s to make sure it is more complete than the content //This is done because the call to time.AfterFunc will not be blocked.It will execute our custom function f in one way at the expiration event. time.Sleep(2 * time.Second) }
Expiration time : 2015-10-31 01:04:42.579988801 +0800 CST. C`s len: 0
The second line shows that field C of the timer does not buffer any element values.This also means that, given a custom function, the default processing method (sending an element value to C representing the absolute expiration time) will not be executed.
Interruptor
The structure type time.Ticker represents the static structure of the breaker.
It is the device that periodically transmits the expiration time.The device behaves somewhat like a clock with only a second hand, except that the interval may not be 1s.
Initialize a Breaker
var ticker *timeTicker = time.NewTicker(time.Second) //Example 1: Stop ticke using time control package main import ( "fmt" "time" ) func main(){ //Initialize the breaker at 2s intervals var ticker *time.Ticker = time.NewTicker(1 * time.Second) go func() { for t := range ticker.C { fmt.Println("Tick at", t) } }() time.Sleep(time.Second * 5) //Blocked, sleep time/ticker time of sleep execution ticker.Stop() fmt.Println("Ticker stopped") }
Tick at 2015-10-31 01:29:34.41859284 +0800 CST Tick at 2015-10-31 01:29:35.420131668 +0800 CST Tick at 2015-10-31 01:29:36.420565647 +0800 CST Tick at 2015-10-31 01:29:37.421038416 +0800 CST Tick at 2015-10-31 01:29:38.41944582 +0800 CST Ticker stopped
Example 2: Stop ticker using channel control
package main import ( "fmt" "time" ) func main(){ //Initialize the breaker at 2s intervals var ticker *time.Ticker = time.NewTicker(100 * time.Millisecond) //num is the specified number of executions num := 2 c := make(chan int, num) go func() { for t := range ticker.C { c <- 1 fmt.Println("Tick at", t) } }() time.Sleep(time.Millisecond * 1500) ticker.Stop() fmt.Println("Ticker stopped") }