Go 1.23中Timer无buffer的实现方式竟是这样!

开发 前端
Go 中的 Timer​ 实现依赖于无缓冲的通道和 Go 的调度器。你可以使用 time.Timer​ 或 time.After 来创建简单的 Timer,或者通过自定义结构体来实现更复杂的 Timer 功能。​

在 Go 1.23 中,Timer 的实现通常是通过 time 包提供的 time.Timer 类型来实现的。Timer 是一个用于在指定时间后触发一次事件的计时器。Timer 的实现并不依赖于缓冲区,而是通过 Go 的调度器和通道机制来实现的。

Timer 的基本实现

Timer 的核心是一个 time.Timer 结构体,它包含一个 time.Timer.C 通道,当计时器到期时,当前时间会被发送到这个通道。

以下是一个简单的 Timer 实现示例:

package main

import (
"fmt"
"time"
)

func main() {
// 创建一个 Timer,设置 2 秒后触发
timer := time.NewTimer(2 * time.Second)

// 等待 Timer 触发
<-timer.C
fmt.Println("Timer expired")

// 如果你想要停止 Timer,可以使用 Stop() 方法
// timer.Stop()
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.

无缓冲区的实现

Timer 的实现并不依赖于缓冲区,而是通过 Go 的通道机制来实现的。Timer.C 是一个无缓冲的通道,当计时器到期时,当前时间会被发送到这个通道。由于通道是无缓冲的,发送操作会阻塞,直到有接收者准备好接收数据。

自定义无缓冲 Timer 实现

如果你想自己实现一个无缓冲的 Timer,可以使用 time.After 函数,它返回一个通道,当指定的时间到达时,通道会接收到一个时间值。

package main

import (
"fmt"
"time"
)

func main() {
// 使用 time.After 创建一个无缓冲的 Timer
timerCh := time.After(2 * time.Second)

// 等待 Timer 触发
<-timerCh
fmt.Println("Timer expired")
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.

更复杂的 Timer 实现

如果你需要更复杂的 Timer 实现,比如可以重置或停止的 Timer,可以参考以下代码:

package main

import (
"fmt"
"time"
)

type MyTimer struct {
duration time.Duration
timer    *time.Timer
resetCh  chan time.Duration
stopCh   chan struct{}
}

func NewMyTimer(duration time.Duration) *MyTimer {
t := &MyTimer{
duration: duration,
resetCh:  make(chan time.Duration),
stopCh:   make(chan struct{}),
}
t.timer = time.NewTimer(duration)
go t.run()
return t
}

func (t *MyTimer) run() {
for {
select {
case <-t.timer.C:
fmt.Println("Timer expired")
return
case newDuration := <-t.resetCh:
if !t.timer.Stop() {
<-t.timer.C
}
t.timer.Reset(newDuration)
case <-t.stopCh:
if !t.timer.Stop() {
<-t.timer.C
}
return
}
}
}

func (t *MyTimer) Reset(duration time.Duration) {
t.resetCh <- duration
}

func (t *MyTimer) Stop() {
t.stopCh <- struct{}{}
}

func main() {
timer := NewMyTimer(2 * time.Second)

time.Sleep(1 * time.Second)
timer.Reset(3 * time.Second)

time.Sleep(2 * time.Second)
timer.Stop()
fmt.Println("Timer stopped")
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.

在这个示例中,MyTimer 是一个自定义的 Timer 实现,它支持重置和停止操作。MyTimer 使用 time.Timer 作为底层实现,并通过通道来接收重置和停止的信号。

总结

Go 中的 Timer 实现依赖于无缓冲的通道和 Go 的调度器。你可以使用 time.Timer 或 time.After 来创建简单的 Timer,或者通过自定义结构体来实现更复杂的 Timer 功能。

责任编辑:武晓燕 来源: Go语言圈
相关推荐

2024-06-24 08:10:34

Java8表达式IDE

2024-09-02 00:30:41

Go语言场景

2019-03-08 10:08:41

网络程序猿代码

2010-01-28 09:45:16

Android Tim

2024-09-02 10:21:21

2024-11-01 12:57:03

2009-07-17 16:32:34

Timer对象Swing

2024-05-10 08:36:40

Go语言对象

2022-06-20 08:56:25

Kafka微服务运维

2022-10-24 00:48:58

Go语言errgroup

2021-04-12 09:35:23

大数据据分析数据

2018-02-02 11:12:01

ANCPU

2019-09-11 10:14:15

苹果iPhone价格

2024-09-09 08:56:03

2016-07-15 10:48:49

无服务器计算虚拟

2020-01-18 09:44:35

无服务器Kubernetes云服务

2017-11-09 14:04:22

无监督学习数据缺失数据集

2009-08-06 16:02:05

无Cookie会话

2021-12-09 08:50:35

Kubernetes增强功能版本更新

2017-12-21 10:07:58

打印机爱普生佳能
点赞
收藏

51CTO技术栈公众号