【GO】19.封装一个简单的ticker

go的time.Timer.stop()以及time.Ticker.stop()在关闭时不会关闭它自己的channel

因此在循环调用这两个结构的channel时要注意,避免内存泄漏。

 

  • 封装Ticker

package ticker

import (
	"fmt"
	"time"
)

type Ticker struct {
	Interval    time.Duration
	Do          func()
	ticker      *time.Ticker
	stopChannel chan bool
}

func NewTicker(d time.Duration, f func()) *Ticker {
	return &Ticker{Interval: d, Do: f, ticker: time.NewTicker(d), stopChannel: make(chan bool)}
}

func (t *Ticker) Start() {
	go func() {
	ForBegin:
		for {
			select {
			case <-t.ticker.C:
				t.Do()
			case <-t.stopChannel:
				break ForBegin
			}
		}

		fmt.Printf("exit ticker range \n")
	}()
}

func (t *Ticker) Stop() {
	t.stopChannel <- true
	t.ticker.Stop()

	fmt.Printf("stop ticker \n")
}

细节:

1.stopChannel在ticker关闭前接受结束状态,保证gorutine可以正确退出。

2.select语句中的break不会跳出循环,需要添加label再通过break跳出。

 

  • 主程序调用代码

package main

import (
	"fmt"
	"gosports/lib/breakoff"
	localTicker "gosports/lib/ticker"
	"time"
)

func main() {
	ticker := localTicker.NewTicker(time.Second, doWrite)
	ticker.Start()

	time.Sleep(time.Second * 5)
	ticker.Stop()

	fmt.Printf("out stop")


	//ticker := time.NewTicker(time.Second * 5)
	//
	//go func(){
	//	for _ = range ticker.C{
	//		fmt.Printf("ticked at %v \n", time.Now())
	//	}
	//}()

	breakoff.Breaking()
}

func doWrite() {
	fmt.Printf("ticker: %v \n", time.Now())
}

 

  • 结果

ticker: 2019-06-28 16:22:57.30141 +0800 CST m=+1.004308335 
ticker: 2019-06-28 16:22:58.301894 +0800 CST m=+2.004783118 
ticker: 2019-06-28 16:22:59.297657 +0800 CST m=+3.000538026 
ticker: 2019-06-28 16:23:00.298235 +0800 CST m=+4.001106591 
ticker: 2019-06-28 16:23:01.298714 +0800 CST m=+5.001576388 
out range 
stop ticker 
out stop

 

  • 番外篇

package breakoff

import (
	"fmt"
	"os"
	"os/signal"
	"syscall"
)

func Breaking() {
	// waitting for exit signal
	exit := make(chan os.Signal)
	stopSigs := []os.Signal{
		syscall.SIGHUP,
		syscall.SIGINT,
		syscall.SIGQUIT,
		syscall.SIGABRT,
		syscall.SIGKILL,
		syscall.SIGTERM,
	}
	signal.Notify(exit, stopSigs...)

	// catch exit signal
	sign := <-exit
	fmt.Printf("stop by exit signal '%s'", sign)

}

防止程序直接退出

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值