Golang初学:time包,Ticker,Timer

go version go1.22.1 windows/amd64

Windows 11 + amd64

x86_64 x86_64 GNU/Linux

---

 

序章

package time

https://pkg.go.dev/time

Package time provides functionality for measuring and displaying time.

测量、显示 时间。

 

本文展示 Ticker、Timer 的 基本使用。

 

type Ticker

源码:

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

通过 这里的 C(只读通道) 接收 tick 数据。

相关方法:

// 函数:创建
func NewTicker(d Duration) *Ticker

// 方法:
// 重置 间隔时间
func (t *Ticker) Reset(d Duration)
// 停止
func (t *Ticker) Stop()

 

创建

1、time.Tick 函数 不推荐

示例:

tk := time.Tick(3 * time.Second)

VS code 此时显示:

using time.Tick leaks the underlying ticker,

consider using it only in endless functions, tests and the main package, and use time.NewTicker here (SA1015)

2、time.NewTicker 推荐。

// 示例
tkptr := time.NewTicker(2 * time.Second)

// 函数签名
func NewTicker(d Duration) *Ticker

 

测试

建立一个 2秒 为周期的 Ticker,循环接收数据,在第5次时,重置(Reset)周期为 5m秒。

代码:

func testNewTicker() {
	tkptr := time.NewTicker(2 * time.Second)
    // 重要
	defer tkptr.Stop()
    
	for i := range [10]int{} {
		tktime := <-tkptr.C
		fmt.Println(i, tktime)

		if i == 4 {
            // 重置
			fmt.Println("call Reset to 5s...")
			tkptr.Reset(5 * time.Second)
		}

		//if i == 7 {
		//	tkptr.Stop()
		//}
	}
	fmt.Println("end.")
}

测试结果:

0 2024-05-13 21:17:29.5750291 +0800 CST m=+2.039318301
1 2024-05-13 21:17:31.5746698 +0800 CST m=+4.038959001
2 2024-05-13 21:17:33.564633 +0800 CST m=+6.028922201
3 2024-05-13 21:17:35.5707819 +0800 CST m=+8.035071101
4 2024-05-13 21:17:37.5620536 +0800 CST m=+10.026342801
call Reset to 5s...
5 2024-05-13 21:17:42.576125 +0800 CST m=+15.040414201
6 2024-05-13 21:17:47.5726813 +0800 CST m=+20.036970501
7 2024-05-13 21:17:52.5662796 +0800 CST m=+25.030568801
8 2024-05-13 21:17:57.5647188 +0800 CST m=+30.029008001
9 2024-05-13 21:18:02.5788418 +0800 CST m=+35.043131001
end.

符合预期。

 

补充说明:

i == 7  的3行,测试了 Stop 方法。打开注释,程序会出现错误“fatal error: all goroutines are asleep - deadlock!”。

此时,应该在 Stop() 后 跳转(goto)到结束。

 

type Timer

源码:

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

也有一个 只读通道 C。

相关方法:

// 函数
// 周期到达后,执行函数 f
func AfterFunc(d Duration, f func()) *Timer
// 标准新建
func NewTimer(d Duration) *Timer
// 方法
// 重置
func (t *Timer) Reset(d Duration) bool
// 停止:在 到达前停止才有意义
func (t *Timer) Stop() bool

 

创建

time.NewTimer 函数:
// 示例
tptr := time.NewTimer(4 * time.Second)

 

测试

代码:

// NewTimer
func testTimer1() {
	fmt.Println("start.", time.Now())
	tptr := time.NewTimer(4 * time.Second)
	defer tptr.Stop()

	t1 := <-tptr.C
	fmt.Println("t1=", t1)

	// 再次调用 出错
	// fatal error: all goroutines are asleep - deadlock!
	// t2 := <-tptr.C
	// fmt.Println(t2)

	// Reset
	// 重置后可以再使用
	tptr.Reset(8 * time.Second)
	t3 := <-tptr.C
	fmt.Println("t3=", t3)

	fmt.Println("end.")
}

测试结果:

start. 2024-05-13 21:47:31.2810254 +0800 CST m=+0.024694601
t1= 2024-05-13 21:47:35.2948188 +0800 CST m=+4.038488001
t3= 2024-05-13 21:47:43.3031721 +0800 CST m=+12.046841301
end.

符合预期。

 

AfterFunc 的简单示例:

func testAfterFunc() {
	tptr := time.AfterFunc(3*time.Second, func() {
		fmt.Println("call f.", time.Now())
	})
	defer tptr.Stop()

    // 4s 大于 tptr 的 3秒
	fmt.Println("停止4s:")
    // 两种方法 暂停
	// 1. ok
	// s4 := <-time.After(4 * time.Second)
	// fmt.Println("s4=", s4)
	// 2. ok
	time.Sleep(4 * time.Second)

	fmt.Println("end.")
}

测试结果:

start. 2024-05-13 21:50:46.199039 +0800 CST m=+0.025212501
停止4s:
call f. 2024-05-13 21:50:49.2040232 +0800 CST m=+3.030196701
end.

 

END.

ben发布于博客园

本文链接:

https://www.cnblogs.com/luo630/p/18190037

ben发布于博客园

参考资料

1、

 

ben发布于博客园

ben发布于博客园

 

posted @ 2024-05-13 22:22  快乐的二当家815  阅读(54)  评论(0编辑  收藏  举报