Go学习笔记—定时器、打点器

Go学习笔记—定时器、打点器

1、定时器

定时器timer的功能是让一段Go代码在指定的时间段后运行一次。

// The Timer type represents a single event.
// When the Timer expires, the current time will be sent on C,
// unless the Timer was created by AfterFunc.
// A Timer must be created with NewTimer or AfterFunc.
type Timer struct {
	C <-chan Time
	r runtimeTimer
}
  • 定时器类型表示单个事件。
  • 定时器过期时,会通过通道C返回当前时间,除非定时器由AfterFunc创建。
  • 必须使用NewTimer或者AfterFunc创建定时器

NewTimer创建一个定时器,该定时器会在至少一个持续时间后在通道上发送当前时间。

使用方法如下:

timer := time.NewTimer(time.Second * 4)
//用变量接收一个传入时间值的方法产生的对象

源码如下:

// NewTimer creates a new Timer that will send
// the current time on its channel after at least duration d.
func NewTimer(d Duration) *Timer {
	c := make(chan Time, 1)
	t := &Timer{
		C: c,
		r: runtimeTimer{
			when: when(d),
			f:    sendTime,
			arg:  c,
		},
	}
	startTimer(&t.r)
	return t
}

AfterFunc等待持续时间结束,然后在自己的goroutine中调用ff返回一个定时器,可使用Stop()方法取消调用。

// AfterFunc waits for the duration to elapse and then calls f
// in its own goroutine. It returns a Timer that can
// be used to cancel the call using its Stop method.
func AfterFunc(d Duration, f func()) *Timer {
	t := &Timer{
		r: runtimeTimer{
			when: when(d),
			f:    goFunc,
			arg:  f,
		},
	}
	startTimer(&t.r)
	return t
}

//f 是一个函数类型,调用时传入goFunc
func goFunc(arg interface{}, seq uintptr) {
	go arg.(func())()
}

一个定时器,指在持续一段时间后某一时刻的独立事件。会通过一个通道进行感知。在通道接收到失效信息之前,会一直处于阻塞状态。

func main(){
    timer1 := time.NewTimer(time.Second * 4) //创建一个4秒后失效的定时器
    
    <- timer1.C //用于感知的通道
    fmt.Println("Timer 1 expired") //输出提示信息
}

//控制台四秒后输出信息
//Timer 1 expired

区别于使用time.Sleep来等待事件的发生,定时器在失效之前可以取消。

func main(){
    timer2 := time.NewTimer(time.Second * 4)
    go func(){
        <-timer2.C
        fmt.Println("Timer 2 expired")
    }()

    stop2 := time2.Stop()
    if stop2 {
        fmt.Println("Timer 2 stopped")
    }
}

//控制台立即输出
//Timer 2 stopped

此例中,如果没有使用协程来控制timer2接收失效信息,控制台会等待4秒输出Timer 2 expired

2、打点器

打点器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
}

NewTicker创建一个打点器,它将定时执行。NewTicker使用方法如下:

ticker := time.NewTicker(time.Second * 1)
//用变量接收一个传入时间值的方法产生的对象

源码如下:

// NewTicker returns a new Ticker containing a channel that will send
// the time on the channel after each tick. The period of the ticks is
// specified by the duration argument. The ticker will adjust the time
// interval or drop ticks to make up for slow receivers.
// The duration d must be greater than zero; if not, NewTicker will
// panic. Stop the ticker to release associated resources.
func NewTicker(d Duration) *Ticker {
	if d <= 0 {
		panic(errors.New("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{
		C: c,
		r: runtimeTimer{
			when:   when(d),
			period: int64(d),
			f:      sendTime,
			arg:    c,
		},
	}
	startTimer(&t.r)
	return t
}
  • NewTicker返回一个打点器,包含一个发送每次打点的时间的通道。
  • 打点时间由生成ticker传入的参数决定。
  • 打点器会调整时间或下降打点次数,来弥补接受速度慢的问题。
  • 接收的时间参数必须大于0,否则会返回错误信息。
  • 使用完毕,要关闭打点器ticker以节约资源。

创建一个对象在,间隔1秒进行一次打点操作,返回打点时间。

func main(){
    ticker := time.NewTicker(time.Second * 1)
    
    go func(){
        for t := range ticker.C{  //从通道中获取时间值
            fmt.Println("Tick at",t)
        }
    }()
    
    time.Sleep(time.second * 3) //模拟函数程序时间
    ticker.Stop()
    fmt.Println("Ticker stopped")
}

//每间隔一秒,输出一条结果
//Tick at 2021-08-16 15:47:48.9317032 +0800 CST m=+1.002859901
//Tick at 2021-08-16 15:47:49.9427927 +0800 CST m=+2.013949401
//Ticker stopped

你可能感兴趣的:(认真学Go,golang,go)