Таймер GO Таймер и временная задача cron

задняя часть
Таймер GO Таймер и временная задача cron

Это первый раз, когда я участвую в Gengwen Challenge.27День, подробности о событии уточняйте:Обновить вызов

Таймер GO Таймер и временная задача cron

В прошлый раз мы говорили о применении swaggo в GO, давайте повторим

  • что такое свагго
  • что такое чванство
  • Как использовать свагго
  • Как протестировать свагго

Если вы все еще немного заинтересованы в применении swaggo в GO, вы можете проверить статьюКак серверная часть на работе предоставляет API? свагго это хорошо

мы можем прийти позжеswaggoПринцип обмена, детальное пониманиеswaggoкак он генерируетсяswaggerДокументация

Сегодня давайте взглянем на **Таймер Таймер и задачу cron в GO**

Давайте посмотрим, как использовать таймер таймера и cron задач на время сегодня.Об их принципах мы подробно поделимся ими в следующих статьях.

Что такое Таймер?

Пакет таймера, представленный в GO, в основном используетсяtime.Timer

таймер на самом деле является таймером одного события

То есть по истечении заданного времени вызвать событие, которое предусмотрено само собойрядбыть уведомленным, потому чтоТаймер выполняется только один раз и заканчивается, поэтому назовите его одиночным событием.

Timerа такжеTickerизСамое главное отличиеОдин здесь

Общий процесс таков:

Среда выполнения Go запускает отдельную сопрограмму

Сопрограмма выполняетtimerprocфункцию, поддерживаетмин куча

Сопрограмма будет периодически просыпаться и читать верхнюю часть кучи.timerобъект, выполнить функцию, соответствующую объекту таймера (то есть вtimer.CОтправьте часть данных, чтобы запустить таймер)

После того, как выполнение будет завершено,мин кучаудалитьtimerобъект

мы создалиtime.Timer, собственно в этоммин кучадобавитьtimerэкземпляр объекта, то нам нужно остановить таймер, то есть использоватьtimer.StopКогда соответствующее значение удаляется из кучи, соответствующийtimerобъект

В этой статье мы не будем сначала подробно объяснять фактический принцип, мы просто сначала применим его, а позже подробно поделимся им.

Все сложно в начале, потом сложно в середине и сложно в конце

Как используется Таймер?

Давайте просто посмотримTimerсоответствующая структура данных

Местоположение:src/time/sleep.go:Timer

TimerПредставляет время, только одно событие происходит после того, как наступает время происходит только один раз, здесьОсобенно важно

TimerТолько один канал открыт для внешнего мира.Когда указанное время истечет, системное время будет записано в канал.Когда время истечет, будет запущено событие, которое будет запущено только один раз, потому что время будет быть на ногах только один раз.

type Timer struct { 
    C <-chan Time
    r runtimeTimer
}

Давайте использовать Timer из следующих сценариев

  • основное использование
  • Использование задержки времени
  • остановить таймер
  • сбросить таймер

основное использование

Давайте установим таймер на 1 с, этот таймер сработает только один раз.

Создайте таймер:

func New*Timer*(d Duration) Timer

Укажите время для созданияTimer,TimerОтсчет времени начинается сразу после его создания, никаких дополнительных команд запуска не требуется

func main() {
    // 创建一个 Timer
   myT := time.NewTimer(1 * time.Second)
    // 从通道中读取数据,若读取得到,说明时间到了
   <- myT.C
   fmt.Println(" 1 s 时间到")

   for {}
}

Использование задержки времени

Установите таймер на 1 секунду с задержкой 2 секунды

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 {}
}

Эффект от запуска кода следующий:

 1 s 时间到  1624757781
 2 s 时间到  1624757783

GO также предоставляет функциюAfterFunc

func AfterFunc(d Duration, f func()) *Timer

Так же можно добиться эффекта задержки, а еще лучше, что после задержки функция, которую мы заполнили, может выполняться.

остановить таймер

TimerЕго можно остановить в любой момент после создания, мы можем использовать time.Stop() для остановки таймера:

func (t *Timer) Stop() bool

Stop()Возвращаемое значение функции равноbool, либоtrue, либоfalse, что означает, истекло ли время ожидания таймера

  • true

Таймер останавливается до истечения времени ожидания, и в будущем события отправляться не будут.

  • false

Таймер останавливается по истечении времени ожидания

Напишите DEMO, установите таймер на 1 с

Если это 1 с, он будет печатать, указывая на то, что время ожидания истекло.

Если не прошло 1 с, канал был закрыт, и время ожидания не истекло.

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 {}
}

В приведенном выше коде необходимость закрытия тайм-аута таймера тесно связана с другим вспомогательным каналом.

Если следующий оператор открыт, таймер может быть нормально закрыт.

Если следующий оператор аннотирован, таймер выключения истекает.

ch <- 1

сбросить таймер

Начните с рыбной памяти, 7-секундный таймер

Немедленно сбросьте таймер на 1-секундный таймер

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 {}
}

После запуска приведенного выше кода эффект выглядит следующим образом:

 开始  1624759572
 1 s 时间到  1624759573

вышесказанноеTimerОн запускается один раз и вступает в силу один раз, что не удовлетворяет всем сценариям, например сценариям, которые выполняются периодически и регулярно.

Мы можем использовать GO внутриTicker

Что такое Тикер?

TickerЭто тоже таймер, но это периодический таймер,

То есть он используется для периодического срабатывания события, путемTickerКонвейер, предоставленный сам по себе, передает событие наружу

TickerТолько один канал выставлен внешнему миру.По истечении указанного времени в канал записывается системное время, то есть событие. Время вышло, только периодическое время вышло

Как использовать Тикер?

Местоположение:src/time/tick.go:Timer

type Ticker structа такжеtype Timer struct {точно так же

// 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
}

О создании таймера и закрытии таймера. Он аналогичен описанному выше методу Timer, давайте перечислим его вместе

СоздайтеTickerТаймер (выделено: это периодический таймер)

func NewTicker(d Duration) *Ticker

закрытиеTickerтаймер

func (t *Ticker) Stop()

Простое приложениеTicker

Установите периодический таймер на 2 секундыTicker

ticker := time.NewTicker(2 * time.Second)
defer ticker.Stop()

// 若通道为空,则阻塞
// 若通道有数据,则读取
// 若通道关闭,则退出
for range ticker.C {
   fmt.Println("ticker ticker ticker ...")
}

Придумайте общую версию DEMO

Периодически выполняем задачи, можем гибко настроить время и конкретные задачи для обработки

  • упаковка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()
}

Выполните приведенный выше код, эффект запуска:

滴答 1 次
滴答 1 次
滴答 1 次
...

срабатывает один разTimer, срабатывает периодическиTicker, мы подали заявку

Что такое крон?

ВидетьcronДрузья не должны быть незнакомы, те, кто пользовался linux, должны быть правы.cronЕще есть идеи

существуетlinuxВнутри мы можем использоватьcrontab -eЧтобы установить временные задачи, в GO мы также можем использоватьcronпакет для настройки запланированных задач

но,linuxВышеупомянутые задачи на время поддерживают только уровень минут или более

Наш GO может поддерживать до секунд

Как используется крон?

Используемые пакеты:"github.com/robfig/cron"

оcronОсновной синтаксис и вlinuxАналогично и при игре, перечислим:

// 每隔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 * * ?

Объясните некоторые из приведенных выше символов:

соответствует всем значениям поля, например.*/1 * * * * ?Второй * за каждую минуту

  • /

представляет интервал роста, например.0 */1 * * * ?Указывает, что выполняется каждую вторую минуту

  • ,

значение перечисления

Например секунды, вы можете написать любое число от 1 до 59 секунд,1,3,5 * * * * ?, что означает, что задача будет выполняться каждые 1, 3, 5 секунд каждой минуты

Необязательный диапазон часов, минут и секунд: 1-59.

День Дополнительный диапазон: 1–31.

Месяц Необязательный диапазон: 1-12

Год Необязательный диапазон: 1-12

Неделя Необязательный диапазон от 0 до 6 для воскресенья-субботы.

представляет диапазон, например.1-10/2 * * * * ?, относится к 1-10 раз в минуту, каждые 2 секунды выполнять задачу

  • ?

используется для обозначенияденьилиНеделю

Возьмем простой пример

Установить выполнение задачи каждые 2 секунды

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Он по-прежнему очень прост в использовании.Заинтересованные друзья, можно много практиковаться.Об их принципах поговорим позже.

Суммировать

  • Что такое таймер
  • Как использовать Таймер
  • что такое тикер
  • Как использовать Тикер
  • что такое крон
  • как использовать крон

Добро пожаловать лайк, подписка, избранное

Друзья, ваша поддержка и поощрение мотивируют меня продолжать делиться и улучшать качество.

Хорошо, вот и на этот раз,Как играть в следующий журнал GO

Технологии открыты, и наш менталитет должен быть открытым. Примите перемены, живите на солнце и двигайтесь вперед.

ямаленький дьяволенок Нежа, добро пожаловать, лайкайте, подписывайтесь и добавляйте в избранное, увидимся в следующий раз~