Go进阶之定时器Ticker的实现示例

 更新时间:2026年02月10日 10:41:23   作者:H_拾忆  
本文主要介绍了Go进阶之定时器Ticker的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

Ticker是周期性定时器.即周期性的触发一个事件.通过Ticker本身提供的管道将事件

传递出去.

Ticker数据结构:

源码位置:src/time/tick.go

type Ticker struct {
    C          <-chan Time // The channel on which the ticks are delivered.
    initTicker bool
}

Ticker对外仅暴露了一个channel.当指定时间到来时就往该channel中写入系统时

间.即一个事件.

1.简单定时任务:

func main() {
    ticker := time.NewTicker(1 * time.Second)

    defer ticker.Stop()

    for range ticker.C {
       log.Println("tick")
    }
}

执行结果:

定时聚合任务:

示例:

func TickerLaunch() {
    //5分钟执行一次.
    ticker := time.NewTicker(5 * time.Minute)

    defer ticker.Stop()
    maxPassenger := 30
    passengers := make([]string, 0, maxPassenger)
    for {
       passenger := GetNewPassenger()
       if passenger != "" {
          passengers = append(passengers, passenger)
       } else {
          time.Sleep(1 * time.Second)
       }
       select {
       case <-ticker.C:
          Launch(passengers)
          passengers = []string{}
       default:
          if len(passengers) >= maxPassenger {
             Launch(passengers)
             passengers = []string{}
          }
       }
    }
}

func Launch(passengers []string) {
    for i := range passengers {
       fmt.Println(passengers[i], "发车了")
    }
}

func GetNewPassenger() string {
    return "乘客"
}

2.Ticker对外接口:

1)创建定时器:

源码位置:src/time/tick.go

func NewTicker(d Duration) *Ticker {
    if d <= 0 {
       panic("non-positive interval for NewTicker")
    }
    // Give the channel a 1-element time buffer.
    // If the client falls behind while reading, we drop ticks
    // on the floor until the client catches up.
    c := make(chan Time, 1)
    t := (*Ticker)(unsafe.Pointer(newTimer(when(d), int64(d), sendTime, c, syncTimer(c))))
    t.C = c
    return t
}

2).停止定时器:

源码位置:src/time/tick.go

// Stop turns off a ticker. After Stop, no more ticks will be sent.
// Stop does not close the channel, to prevent a concurrent goroutine
// reading from the channel from seeing an erroneous "tick".
func (t *Ticker) Stop() {
    if !t.initTicker {
       // This is misuse, and the same for time.Timer would panic,
       // but this didn't always panic, and we keep it not panicking
       // to avoid breaking old programs. See issue 21874.
       return
    }
    stopTimer((*Timer)(unsafe.Pointer(t)))
}

流程图:

总流程图:

3.简单接口:

在有些场景下.启动一个定时器后.该定时器永远不会停止.比如定时轮询任务.此时可

以使用一个简单的Tick函数来获取定时器的管道.函数如下:

源码位置:src/runtime/tick.go

func Tick(d Duration) <-chan Time {
    if d <= 0 {
       return nil
    }
    return NewTicker(d).C
}

从源码可以看出其实是创建了一个Ticker.然后只返回了管道.并没有返回ticker.所以

没有办法停止.

4.错误示例:

当Ticker用于for循环时.很容易出现意想不到的资源泄漏问题.

示例:

func WrongTicker() {
    for  {
       select {
       case <-time.Tick(time.Second):
          log.Printf("resource leak!")
       }
    }
}

上面的代码.select每次检测case语句都会创建一个定时器.for循环又会不断的执行

select语句.系统里会有越来越多的定时器不断地消耗CPU资源.最终CPU资源被耗

到此这篇关于Go进阶之定时器Ticker的实现示例的文章就介绍到这了,更多相关Go 定时器Ticker内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 一文详解go中如何实现定时任务

    一文详解go中如何实现定时任务

    定时任务是指按照预定的时间间隔或特定时间点自动执行的计划任务或操作,这篇文章主要为大家详细介绍了go中是如何实现定时任务的,感兴趣的可以了解下
    2023-11-11
  • golang 实现每隔几分钟执行一个函数

    golang 实现每隔几分钟执行一个函数

    这篇文章主要介绍了golang 实现每隔几分钟执行一个函数,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • GO语言的IO方法实例小结

    GO语言的IO方法实例小结

    这篇文章主要介绍了GO语言的IO方法实例小结,Docker的火爆促成了当下新兴的Go语言人气的大幅攀升,需要的朋友可以参考下
    2015-10-10
  • 使用Go语言编写一个简单的Web框架

    使用Go语言编写一个简单的Web框架

    Go语言(又称Golang)因其高效的性能和简洁的语法,在编写Web框架方面表现出色,下面将详细介绍如何使用Go语言编写一个简单的Web框架,文中有详细的代码供大家参考,需要的朋友可以参考下
    2024-05-05
  • 完美解决golang go get私有仓库的问题

    完美解决golang go get私有仓库的问题

    这篇文章主要介绍了完美解决golang go get私有仓库的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-05-05
  • go语言实现mqtt协议的实践

    go语言实现mqtt协议的实践

    MQTT是一个基于客户端-服务器的消息发布/订阅传输协议。本文主要介绍了go语言实现mqtt协议的实践,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-09-09
  • golang标准库SSH操作示例详解

    golang标准库SSH操作示例详解

    文章介绍了如何使用Golang的crypto/ssh库实现SSH客户端功能,包括连接远程服务器、执行命令、捕获输出以及与os/exec标准库的对比,本文给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2024-12-12
  • Golang导入包的几种方式(点,别名与下划线)

    Golang导入包的几种方式(点,别名与下划线)

    这篇文章主要介绍了Golang导入包的几种方式(点,别名与下划线),文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-02-02
  • Go语言程序查看和诊断工具详解

    Go语言程序查看和诊断工具详解

    这篇文章主要为大家详细介绍了Go语言程序查看和诊断工具,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-11-11
  • golang实现循环队列的示例代码

    golang实现循环队列的示例代码

    循环队列是一种使用固定大小的数组来实现队列的数据结构,本文主要介绍了golang实现循环队列的示例代码,具有一定的参考价值,感兴趣的可以了解一下
    2024-07-07

最新评论