GO timer Timer and timing task cron
Last time we talked about the swaggo application in GO, let’s review it
- What is swaggo
- What is swagger
- How to use swapgo
- How to test swapgo
If you are still interested in the application of swaggo in GO, you can check the article How does the backend provide the API during work? swaggo is very good
Then we can come to a swaggo
principle of sharing, thin look swaggo
how is generated swagger
document
Today, let’s take a look at the timer in GO and the timing task cron
Let’s take a look at how the timer and cron are used today. We will share in detail in the follow-up articles about their principles.
What is Timer?
It is a timer package provided in GO, mainly with time.Timer
timer is actually a single event timer
That is to say, an event is triggered after a specified time. This event channel provided by itself. Because the Timer is executed only once and ends, it is called a single event
Timer
and Ticker
of most important difference one is here
looks like this: 16125c052562cd
A separate coroutine will be started when Go is running
The coroutine executed a timerproc
and maintained a minimum heap
The coroutine will be periodically woken up and read the timer
object at the top of the heap, and execute the function corresponding to the timer object (that is, send a piece of data timer.C
After execution, the timer
object will be removed from the minimum heap
time.Timer
we created is actually adding a timer
minimum heap , then we need to stop the timer, that is timer.Stop
, we delete the corresponding timer
object from this heap
This article does not explain the actual principle in detail, we will briefly apply it first, and we will share it in detail later
Everything is hard at the beginning, then hard in the middle, and hard at the end
How to use Timer?
Let's take a brief look at the data structure corresponding to Timer
The location is: src/time/sleep.go:Timer
Timer
represents a timing, only one event occurs after the time comes
It happens only once, here particularly important
Timer
only exposes one channel to the outside. When the specified time is up, the system time will be written to the channel. When the time is up, the event will be triggered once, and it will only be triggered once, because the time will only reach once
type Timer struct {
C <-chan Time
r runtimeTimer
}
from the following scenarios respectively
- Basic use
- Time delay use
- Stop timer
- Reset timer
Basic use
Let's set a timer in 1s, this timer will only trigger once
Create a timer:
func New*Timer*(d Duration) Timer
Specify a time to create a Timer
, Timer
will start timing once it is created, no additional start command is required
func main() {
// 创建一个 Timer
myT := time.NewTimer(1 * time.Second)
// 从通道中读取数据,若读取得到,说明时间到了
<- myT.C
fmt.Println(" 1 s 时间到")
for {}
}
Time delay use
Set a timer of 1 second, and then delay for 2 seconds
func main() {
// 创建一个 Timer
myT := time.NewTimer(1 * time.Second)
<- myT.C
fmt.Println(" 1 s 时间到 ",time.Now().Unix())
// 延时 2 秒
<-time.After(2 * time.Second)
fmt.Println(" 2 s 时间到 ",time.Now().Unix())
for {}
}
The execution effect of running code is as follows:
1 s 时间到 1624757781
2 s 时间到 1624757783
GO also provides a function AfterFunc
func AfterFunc(d Duration, f func()) *Timer
It is also possible to achieve the effect of delay. Better yet, after the delay, the function we filled in can be executed
Stop timer
Timer can be stopped at any time after creation, we can use time.Stop() to stop the timer:
func (t *Timer) Stop() bool
Stop()
function return value is bool
, either true
or false
, which means whether the timer expires
- true
Stop before the timer expires, and no more events will be sent in the future
- false
The timer is stopped after timeout
Write a DEMO, set the timer of 1 s
If it is 1 s, then print, indicating that it has timed out
If it does not reach 1 s, the channel has been closed, and it has not timed out
func testChannelTimeout(conn chan int) bool {
// 设置 1 秒的定时器,若在到了1 s ,则进行打印,说明已经超时
timer := time.NewTimer(1 * time.Second)
select {
case <-conn:
if (timer.Stop()){
fmt.Println("timer.Stop()")
}
return true
case <-timer.C: // timer 通道超时
fmt.Println("timer Channel timeout!")
return false
}
}
func main() {
ch := make(chan int, 1)
// 若打开如下语句,则可以正常关闭定时器
// 若注释如下语句,则关闭定时器超时
//ch <- 1
go testChannelTimeout(ch)
for {}
}
In the above code, whether the shutdown timer expires is closely related to another auxiliary channel
If you open the following statement, you can turn off the timer normally
If you comment the following statement, turn off the timer timeout
ch <- 1
Reset timer
Set a fish’s memory at the start, a 7-second timer
Immediately reset the timer to a 1-second timer
func main() {
// 创建一个 Timer 鱼的记忆
fmt.Println(" 开始 ", time.Now().Unix())
myT := time.NewTimer(7 * time.Second)
// 重置定时器为 1 s
myT.Reset(1 * time.Second)
<-myT.C
fmt.Println(" 1 s 时间到 ", time.Now().Unix())
for {}
}
After running the above code, the effect is as follows:
开始 1624759572
1 s 时间到 1624759573
The above Timer
is triggered once and takes effect once, which cannot satisfy all scenarios. For example, the scenario that is executed periodically is not satisfied.
We can use Ticker
What is Ticker?
Ticker
is also a timer, but it is a periodic timer,
In other words, it is used to trigger an event periodically, and pass the event out Ticker
Ticker
only exposes one channel to the outside. When the specified time is up, the system time, that is, an event, is written to the channel. The time here is up, only the periodic time is up
How is Ticker used?
The location is: src/time/tick.go:Timer
type Ticker struct
and type Timer struct {
exactly the same
// 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
}
About creating timers and closing timers are similar to the above Timer methods, let’s enumerate them together
Create Ticker
timer (emphasis: this is a periodic timer)
func NewTicker(d Duration) *Ticker
Disable Ticker
timer
func (t *Ticker) Stop()
Simple application Ticker
Set a 2-second periodic timer Ticker
ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()
// 若通道为空,则阻塞
// 若通道有数据,则读取
// 若通道关闭,则退出
for range ticker.C {
fmt.Println("ticker ticker ticker ...")
}
Come to a general version of the DEMO
Periodic execution of tasks, we can flexibly set the time and specific tasks
- Encapsulate the call of
Ticker
// 定义函数类型
type Fn func() error
// 定时器中的成员
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,
}
}
// 启动定时器需要执行的任务
func (t *MyTicker) Start() {
for {
select {
case <-t.MyTick.C:
t.Runner()
}
}
}
func testPrint(){
fmt.Println(" 滴答 1 次")
}
func main() {
t := NewMyTick( 1 ,testPrint)
t.Start()
}
Execute the above code and run the effect:
滴答 1 次
滴答 1 次
滴答 1 次
...
Trigger once Timer
, periodic triggered Ticker
, we have applied to the
What is cron?
You should be familiar with cron
who have used Linux should still have some ideas cron
In linux
we can use crontab -e
to set timed tasks, in GO, we can also use cron
package to set timed tasks
However, the above-mentioned timing tasks in linux
Our GO can support to the second level
How is cron used?
Package used: "github.com/robfig/cron"
About cron
basic grammar and in linux
when playing a similar, let's briefly enumerate them:
// 每隔1秒执行一次
*/1 * * * * ?
// 每隔1分钟执行一次
0 */1 * * * ?
// 每天0点执行一次
0 0 0 * * ?
// 每月1号凌晨1点执行一次
0 0 1 1 * ?
// 在1分、2分、3分执行一次
0 1,2,3 * * * ?
// 每天的0点、1点、2点执行一次
0 0 0,1,2 * * ?
Explain some of the above characters:
- *
Match all the values of the field, for example */1 * * * * ?
the second * means every minute
- /
Represents the growth interval, such as 0 */1 * * * ?
, which is executed every minute
- ,
Enumerated value
For example, in seconds, you can write any number from 1 to 59 seconds, 1,3,5 * * * * ?
, which means that the task will be executed in 1, 3, and 5 seconds every minute
The optional range of hour, minute, and second is 1-59
The daily range is 1-31
Month can be selected from 1-12
Years can be selected from 1-12
The week range is 0-6, which means Sunday-Saturday
- -
Represents a range, such as 1-10/2 * * * * ?
, refers to 1-10 per minute, and executes the task every 2 seconds
- ?
It is used to represent day or week
is a simple example
Set to execute the task every 2 seconds
func main() {
i := 0
c := cron.New()
spec := "*/2 * * * * ?"
err := c.AddFunc(spec, func() {
i++
fmt.Println("cron times : ", i)
})
if err != nil {
fmt.Errorf("AddFunc error : %v",err)
return
}
c.Start()
defer c.Stop()
select {}
}
cron
is still very simple to use. If you are interested, you can practice more. Regarding their principles, let's follow up.
Summarize
- What is Timer
- How to use Timer
- What is Ticker
- How to use Ticker
- What is cron
- How to use cron
Welcome to like, follow, favorite
Friends, your support and encouragement are my motivation to keep sharing and improve quality
Okay, that’s it for this time. How to play the next GO log
Technology is open, and our mindset should be more open. Embrace the change, live toward the sun, and work hard to move forward.
I am , the little magic boy, welcome to like and follow the collection, see you next time~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。