Go的标准包time里提供了两种定时器,一种是标准定时器,另一种是循环定时器。
标准定时器
标准定时器在到达指定时间时仅触发一次。time包提供了若干函数和类型来表示这种定时器:
// After() 在经过时长 d 之后,向返回的只读信道发送当前时间
func After(d Duration) <-chan Time
// Timer 表示仅触发一次事件的定时器
type Timer struct {
C <-chan Time // 在Timer触发时会向C发送当前时间
// ...
}
// 在经过时长 d 之后调用 f,返回的Timer可用于结束定时器
// f 在新的协程调用
func AfterFunc(d Duration, f func()) *Timer
// 创建新的定时器
func NewTimer(d Duration) *Timer
// 重置定时器,以 d 为触发时间
func (t *Timer) Reset(d Duration) bool
// 停止定时器
func (t *Timer) Stop() bool
举例
After()的使用:
package main
import (
"fmt"
"time"
)
func main() {
done := make(chan struct{}) // 用来等待协程结束
go func(ch <-chan time.Time) {
fmt.Printf("Now is %s\n", <-ch) // 等待信道接收数据,接收到之后打印当前时间
done <- struct{}{} // 通知主线程协程退出
}(time.After(time.Second * 3)) // 调用After,将返回的只读信道传递给协程函数
<-done
close(done)
}
AfterFunc()的使用:
package main
import (
"fmt"
"time"
)
func main() {
done := make(chan struct{}) // 用来等待协程结束
go time.AfterFunc(time.Second*3, func() {
fmt.Println("Print after 3 seconds")
done <- struct{}{} // 通知主协程结束
})
fmt.Println("Print in main")
<-done
close(done)
}
Timer的使用:
package main
import (
"fmt"
"time"
)
func main() {
done := make(chan struct{}) // 用来等待协程结束
timer := time.NewTimer(time.Second * 3)
go func() {
fmt.Printf("Now is %s\n", <-timer.C)
done <- struct{}{}
}()
fmt.Println("Print in main")
<-done
close(done)
}
循环定时器
循环定时器在每次到达指定时间时都触发事件。time包中的循环定时器都是永久执行的定时器,直到手动关闭它。time中没有可以指定次数的循环定时器。time包提供了如下循环定时器API:
// 每经过时长 d 之后,都向返回的只读信道发送当前时间
// 注意没办法关闭该函数产生的定时器,因此该方法通常用于
// 在程序运行中一直存在且不需要关闭定时器的场合,比如后台备份
func Tick(d Duration) <-chan Time
// Ticker表示循环定时器
type Ticker struct {
C <-chan Time // 定时器触发时向这个信道发送当前时间
// ...
}
// 创建新的Ticker
func NewTicker(d Duration) *Ticker
// 停止Ticker
func (t *Ticker) Stop()
举例
Tick()的使用:
package main
import (
"fmt"
"sync"
"time"
)
func main() {
var wg sync.WaitGroup
wg.Add(10)
go func(ch <-chan time.Time) {
for t := range ch {
fmt.Printf("Backup at %s\n", t)
wg.Done()
}
}(time.Tick(time.Second * 1))
wg.Wait()
}
Ticker的使用
package main
import (
"fmt"
"sync"
"time"
)
func main() {
ticker := time.NewTicker(time.Second * 1)
wg := sync.WaitGroup{}
wg.Add(10)
go func() {
for t := range ticker.C {
fmt.Printf("Backup at %s\n", t)
wg.Done()
}
}()
wg.Wait()
ticker.Stop()
}