This is the 24th day of my participation in the August More Text Challenge
This article appears in my column:Let’s Golang
Talk about the fixed time timer and periodic time timer of Go
When we wanted to do delayed execution in scheduling, we could use pipe blocking until someone wrote something into the pipe, and we could use sleep to sleep, but sleeping, the coroutine didn’t do anything and took up resources. So we’re going to use the timer that we’re going to talk about, and we’re not going to use up resources like sleep.
Let’s start with the following code:
package main
import (
"fmt"
"time"
)
func main(a) {
timer := time.NewTimer(3 * time.Second)
fmt.Println("Timer created!")
fmt.Println(time.Now())
// Block for 3 seconds to read the time
x := <- timer.C
// C is a one-way read-only pipe
fmt.Println(x)
}
Copy the code
The result looks like this:
Timer created!2021- 08- 24 14:02:28.6664158 +0800 CST m=+0.012997601
2021- 08- 24 14:02:31.670071 +0800 CST m=+3.016652801
Copy the code
As you can see, the result is basically the same as what we want to achieve. After creating the three-second timer, block for three seconds before reading the time.
Let’s take a look at this
x := <- timer.C
Copy the code
C is a one-way read-only pipe:
type Timer struct {
C <-chan Time
r runtimeTimer
}
Copy the code
If you wanted to describe a one-way write-only pipe, you would write:
C chan <- Time
Copy the code
But if we want to achieve the same goal, we can use the following simpler way:
func main(a) {
fmt.Println(time.Now())
x := <- time.After(3*time.Second)
fmt.Println(x)
}
Copy the code
Use time.after () to wait a specified amount of time, and then send the current time on the returned pipe. It is equivalent to NewTimer(d).c. The garbage collector does not collect the underlying Timer until the Timer is triggered. If efficiency is a concern, use NewTimer instead and end with a call to timer.stop when the Timer is no longer needed.
Of course we can also use the following method, both methods can be used:
x := <- time.NewTimer(3 * time.Second).C
Copy the code
The fixed time timer is a time bomb set to three seconds that will explode in three seconds. Now let’s look at the periodic time timer!
func main(a) {
ticker := time.NewTicker(1 * time.Second)
var i int
for{
x := <- ticker.C
fmt.Print("\r",x)
i++
if i>3{
// Stopping the stopwatch causes ticker.C to never read data,
// This will cause a deadlock.
ticker.Stop()
break
}
}
fmt.Println("The clock is over.")}Copy the code
Set a periodic timer, read data from the pipe every second, and output until I >3. Use ticker.stop () to terminate the timer, then Stop the loop, and tell you that the timer is finished.
If you still want to read after the timer is over, the following situation will occur!
fatal error: all goroutines are asleep – deadlock!
Deadlock! So we need break here.