Go by Example - Timers and Tickers

Go by Example - Timers and Tickers

介绍go中的计时器和滴答器

Timers

我们经常希望在未来的某个时间点执行 Go 代码,或者在某个时间间隔内重复执行。Go 内置的定时器和 ticker 功能可以轻松完成这两项任务。我们先来看看计时器,然后再看看 ticker。

timers.go
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
package main

import (
"fmt"
"time"
)

func main() {
// 计时器代表未来的一个事件
// 您可以告诉定时器要等待多长时间,定时器就会提供一个到时会收到通知的通道
// 该计时器将等待 2 秒
timer1 := time.NewTimer(2 * time.Second)

// <-timer1.C 在定时器通道 C 上阻塞,直到它发送一个值,表明定时器启动
<-timer1.C
fmt.Println("Timer 1 fired")

// 如果你只想等待,可以使用 time.Sleep
// 定时器有用的一个原因是,你可以在它启动前取消定时器。下面就是一个例子
timer2 := time.NewTimer(time.Second)
go func() {
<-timer2.C
fmt.Println("Timer 2 fired")
}()
stop2 := timer2.Stop()
if stop2 {
fmt.Println("Timer 2 stopped")
}

// 给定时器 2 足够的发射时间(如果它要发射的话),以显示它确实停止了
time.Sleep(2 * time.Second)
}

第一个定时器将在我们启动程序后约 2 秒启动,但第二个定时器应在启动前停止。

log
1
2
3
$ go run timers.go
Timer 1 fired
Timer 2 stopped

Tickers

定时器用于在未来执行一次任务,而滴答器则用于定期重复执行任务。下面是一个计时器的示例,它定期滴答作响,直到我们停止。

tickers.go
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
package main

import (
"fmt"
"time"
)

func main() {
// 滴答器使用与定时器类似的机制:一个发送值的通道
// 在这里,我们将使用通道上的 select 内置函数来等待每 500ms 到达的值
ticker := time.NewTicker(500 * time.Millisecond)
done := make(chan bool)

go func() {
for {
select {
case <-done:
return
case t := <-ticker.C:
fmt.Println("Tick at", t)
}
}
}()

// 滴答器可以像计时器一样停止
// 滴答器一旦停止,其通道上就不会再收到任何数值。我们将在 1600ms 后停止
time.Sleep(1600 * time.Millisecond)
ticker.Stop()
done <- true
fmt.Println("Ticker stopped")
}

当我们运行这个程序时,滴答声应该滴答 3 次才会停止。

log
1
2
3
4
5
$ go run tickers.go
Tick at 2012-09-23 11:29:56.487625 -0700 PDT
Tick at 2012-09-23 11:29:56.988063 -0700 PDT
Tick at 2012-09-23 11:29:57.488076 -0700 PDT
Ticker stopped

参考链接

作者

孤独小狼

发布于

2024-03-17

更新于

2024-03-17

许可协议

评论