This is the 27th day of my participation in Gwen Challenge
GO timers Timer and scheduled task Cron
Last time we talked about swaggo in GO, let’s review
- What is swaggo
- What is the swagger
- How to use Swaggo
- How to test Swaggo
If you’re interested in the swagGo application in GO, check out how the back end provides the API at work. Swaggo is very good
We can do it again laterswaggo
The principle of sharing, thin understandingswaggo
How is it generatedswagger
The document
Today let’s take a look at GO’s Timer and Timer task cron
Let’s take a look at how timers and timed task crons are used today. We will share more about their principles in a future article
What is a Timer?
GO provides a Timer package, mainly using time.Timer
A timer is actually a single event timer
That is, an event is triggered after a specified time, and this event is notified through the channel provided by the Timer itself. Since the Timer is executed only once, it is called a single event
This is one of the most important differences between the Timer and the Ticker
The general process looks like this:
A separate coroutine is launched when Go runs
This coroutine performs a function of TimerProc to maintain a minimal heap
The coroutine periodically wakes up and reads the timer object at the top of the heap, executing the timer object’s corresponding function (i.e., sending a piece of data in timer.c to trigger the timer).
After execution, the timer object is removed from the minimum heap
When we create a time.Timer, we actually add a Timer object instance to the smallest heap, so we need to Stop the Timer, that is, when we use timer.stop, we remove the corresponding Timer object from the heap
This article will not elaborate on the practical principles, we will briefly apply it first, and share details later
All things are difficult at the beginning, then in the middle, and finally at the end
How is Timer used?
Let’s take a quick look at the data structure of the Timer
Location: SRC /time/sleep.go:Timer
Timer stands for one time, and when the time comes, only one event happens, only one event happens, so this is particularly important
Timer exposes only one channel to the outside world. When the specified time is up, the system time will be written into this channel. When the time is up, an event will be triggered
type Timer struct {
C <-chan Time
r runtimeTimer
}
Copy the code
Let’s use the Timer in the following scenarios
- The basic use
- Time delay
- Stop timer
- Reset timer
The basic use
Let’s set a timer for 1s that will only trigger once
Create a timer:
func New*Timer*(d Duration) Timer
Specify a time to create a Timer, and the Timer starts as soon as it is created. No additional start command is required
func main(a) {
// Create a Timer
myT := time.NewTimer(1 * time.Second)
// Read data from the channel, if read, the time is up
<- myT.C
fmt.Println("One s time is up.")
for{}}Copy the code
Time delay
Set a timer for 1 second and delay by 2 seconds
func main(a) {
// Create a Timer
myT := time.NewTimer(1 * time.Second)
<- myT.C
fmt.Println("One s time is up.",time.Now().Unix())
// Delay 2 seconds
<-time.After(2 * time.Second)
fmt.Println("Two seconds is up.",time.Now().Unix())
for{}}Copy the code
The execution effect of the running code is as follows:
1 s to 1624757781 2 s to 1624757783Copy the code
GO also provides a function AfterFunc
func AfterFunc(d Duration, f func()) *Timer
We can delay it, and even better, after we delay it, we can execute the function that we’re filling in
Stop timer
After the Timer is created, it can be stopped at any time. We can use time.stop () to Stop the Timer:
func (t *Timer) Stop() bool
The Stop() function returns bool, either true or false, indicating whether the timer times out
- true
If the timer expires, no more events will be sent
- false
The timer is stopped after the timeout
Write a DEMO and set the timer for 1 s
If at 1 s, print, indicating timeout
If the channel has not been closed before 1 s, it has not timed out
func testChannelTimeout(conn chan int) bool {
// Set a timer of 1 second. If the timer reaches 1 second, print it
timer := time.NewTimer(1 * time.Second)
select {
case <-conn:
if (timer.Stop()){
fmt.Println("timer.Stop()")}return true
case <-timer.C: // The timer channel times out
fmt.Println("timer Channel timeout!")
return false}}func main(a) {
ch := make(chan int.1)
// If the following statement is enabled, the timer can be normally shut down
// If the following statement is commented, the timer timeout is disabled
//ch <- 1
go testChannelTimeout(ch)
for{}}Copy the code
In the above code, whether to turn off the timer timeout is closely related to another secondary channel
If the following statement is enabled, the timer can be normally disabled
If the following statement is commented, the timer times out
ch <- 1
Reset timer
Start with a fish memory, a 7 second timer
Reset the timer to a one-second timer immediately
func main(a) {
// Create a memory of the Timer fish
fmt.Println("Start", time.Now().Unix())
myT := time.NewTimer(7 * time.Second)
// Reset the timer to 1s
myT.Reset(1 * time.Second)
<-myT.C
fmt.Println("One s time is up.", time.Now().Unix())
for{}}Copy the code
After running the above code, the effect is as follows:
Start 1624759572 1 s time to 1624759573Copy the code
The above Timer is triggered once and takes effect once, which cannot meet all scenarios, such as the scenario of periodic execution
We can use the Ticker in GO
What is a Ticker?
A Ticker is also a timer, but it’s a periodic timer,
That is, it is used to trigger an event periodically, passing it out through a pipe provided by the Ticker itself
The Ticker exposes only one channel to the outside world. When the specified time is up, the system time, that is, an event, is written to the channel. Here the time is up, only the periodic time is up
How is Ticker used?
The position is: SRC /time/tick.go:Timer
Type Ticker struct and type Timer struct {are identical
// A Ticker holds a channel that delivers ``ticks'' of a clock
// at intervals.
type Ticker struct {
C <-chan Time // The channel on which the ticks are delivered.
r runtimeTimer
}
Copy the code
Creating and closing timers is similar to the above Timer methods, let’s list them together
Create Ticker timer (emphasis: this is a periodic timer)
func NewTicker(d Duration) *Ticker
The Ticker timer is disabled
func (t *Ticker) Stop()
Simple applicationTicker
Set the periodic timer Ticker to 2 seconds
ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()
// If the channel is empty, it is blocked
// If the channel has data, then read
// Exit if the channel is closed
for range ticker.C {
fmt.Println("ticker ticker ticker ...")}Copy the code
Let’s do a general version DEMO
Periodic execution of tasks, we can flexibly set the time, and specific tasks to deal with
- encapsulation
Ticker
The call
// Define the function type
type Fn func(a) error
// Member of the timer
type MyTicker struct {
MyTick *time.Ticker
Runner Fn
}
func NewMyTick(interval int, f Fn) *MyTicker {
return &MyTicker{
MyTick: time.NewTicker(time.Duration(interval) * time.Second),
Runner: f,
}
}
// Start the task to be executed by the timer
func (t *MyTicker) Start(a) {
for {
select {
case <-t.MyTick.C:
t.Runner()
}
}
}
func testPrint(a){
fmt.Println("One tick")}func main(a) {
t := NewMyTick( 1 ,testPrint)
t.Start()
}
Copy the code
Execute the above code, the operation effect:
Tick 1, tick 1, tick 1...Copy the code
A Timer that fires once, a Ticker that fires periodically, we’ve used it all
What is a cron?
If you’ve ever used Linux, you probably have some ideas about Cron
In Linux, we can use crontab -e to set scheduled tasks. In GO, we can also use cron package to set scheduled tasks
However, in Linux, the above scheduled tasks can only be performed at a higher level than minutes
We can support GO to the second level
How to use Cron?
Package to use: “github.com/robfig/cron”
The basic syntax of Cron is similar to that of Linux. Here are some examples:
// Every 1 second */1 * * * *? // Execute 0 */1 * * * every 1 minute? 0 0 0 * *? 0 0 1 1 *? // Execute 0, 1,2,3 * * *? 0 0 0,1,2 * *?Copy the code
Explain some of the characters above:
Match all values of the field, for example, */1 * * * *? The second * is for every minute
- /
For example, 0 */1 * * *? Indicates that the command is executed every minute
- .
Enumerated values
For example, seconds can be any number from 1 to 59 seconds, 1,3,5 * * * *? “, which means 1, 3, 5 seconds per minute
The optional range of hours, minutes, and seconds is 1-59
The range of daily options is 1-31
Monthly options range from 1 to 12
Year options range from 1 to 12
Week ranges from 0 to 6 for Sunday-Saturday
Represents a range, for example, 1-10/2 * * * *? , refers to 1 to 10 minutes per minute, every 2 seconds, perform the task
- ?
Used to indicate the day or week
Let’s do a simple example
Set the task to be executed every 2 seconds
func main(a) {
i := 0
c := cron.New()
spec := "*/2 * * * *?"
err := c.AddFunc(spec, func(a) {
i++
fmt.Println("cron times : ", i)
})
iferr ! =nil {
fmt.Errorf("AddFunc error : %v",err)
return
}
c.Start()
defer c.Stop()
select{}}Copy the code
Cron is very simple to use. If you are interested in it, you can practice it a lot. We will talk about its principle later
conclusion
- What is the Timer
- How to use Timer
- What is the Ticker
- How is Ticker used
- What is the cron
- How to use Cron
Welcome to like, follow and favorites
Friends, your support and encouragement, I insist on sharing, improve the quality of the power
Ok, that’s all for now. How to play the log of GO next time
Technology is open, our mentality, should be more open. Embrace change, live in the sun, and strive to move forward.
I am Nezha, welcome to like, see you next time ~