区别和使用注意事项

时间:2025-03-03 15:21:57

首先和 属于定时器,二者的区别在于

timer : 到固定时间后会执行一次,请注意是一次,而不是多次。但是可以通过reset来实现每隔固定时间段执行

ticker : 每隔固定时间都会触发,多次执行.  具体请查看下面示例1

: 用于实时超时控制,常见主要和select  channel结合使用.查看代码示例2

//示例1
package main

import (
	"fmt"
	"sync"
	"time"
)

// timer 和 ticker 区别
// timer  是到固定时间后会执行一次
// ticker 每隔固定时间都会触发  常用的一种定时器
func main() {
	var wg 
	(2)

	timer := ( * 3)
	go func(t *) {
		defer ()
		for {
			<-
			("timer", ().Format("2006-01-02 15:04:05"))
       //利用Reset可以实现timer每隔固定时间段触发。reset 重新开始计时,如果调用时 t 还在等待中会返回真;如果 t已经到期或者被停止了会返回假。可自行打印查看结果
            // (2 * )
			//expire := (2 * )
			//("expire:",expire)
		
		}
	}(timer)


	ticker := ( * 4)
	go func(t *) {
		defer ()
		for {
			<-
			("ticker", ().Format("2006-01-02 15:04:05"))
		}
	}(ticker)

	()

}


//timer未使用reset的执行结果如下:
/*
timer 2021-01-05 15:06:34
ticker 2021-01-05 15:06:35
ticker 2021-01-05 15:06:39
ticker 2021-01-05 15:06:43
....
....
....
*/
// timer使用reset的执行结果如下:
/*
timer 2021-01-05 15:19:08
ticker 2021-01-05 15:19:09
timer 2021-01-05 15:19:10
timer 2021-01-05 15:19:12
ticker 2021-01-05 15:19:13
timer 2021-01-05 15:19:14
timer 2021-01-05 15:19:16
...
...
...
*/
// 示例2
package main

import (
    "time"
    "fmt"
)

func main() {
    ch := make(chan string)

    go func() {
        ( * 2)

        ch <- "result"
    }()

    select {
    case res := <-ch:
        (res)
    case <-( * 1):
        ("timeout")
    }
}

再知道二者的区别之后,是否发现了上面有缺陷。没有关闭定时器的执行。定时器未关闭!!!!大家会想到stop ,使用stop注意是在协程内还是携程外,以及使用的场景业务

协程退出时需要关闭,避免资源l浪费,使用defer () 

package main

import (
	"fmt"
	"time"
)

//定时器的stop
func main() {

	// 协程内的定时器 stop  在协程结束时,关闭默认资源定时器,channel 具体根据业务来看
	go func() {
		ticker := (5 * )
		// 此处 可以简化为defer ()
		defer func() {
			("stop")
			()
		}()
	
	   select {
	   case <- :
			("ticker..." )
		}
	}()

	// 停止ticker
	stopChan := make(chan bool)
	ticker := (5 * )
	go func(ticker *) {
		defer func() {
			()
			("Ticker2 stop")
		}()
		for {
			select {
			case s := <-:
				("Ticker2....",s)
			case stop := <-stopChan:
				if stop {
					("Stop")
					return
				}
			}
		}

	}(ticker)
	// 此处的stop 并不会结束上面协程,也不会打印出 Ticker2 stop  只能借助stopChan,让协程结束时关闭ticker或者协程出现panic时执行defer
	//()
	stopChan <- true
	close(stopChan)
	
	( * 10)
	("main end")
	
}

实际使用场景的代码示例

package main

import (
	"fmt"
	"time"
)

// 每秒钟调⽤⼀次 proc 并保证程序不退 出
func main() {
	go func() {
		t := ( * 1)
		defer func() {
			()
		}()
		// 1 在这⾥需要你写算法
		// 2 要求每秒钟调⽤⼀次proc函数
		// 3 要求程序不能退出
		for {
			select {
			case <-:
				go func() {
					defer func() {
						if err := recover(); err != nil {
							(err)
						}
					}()
					proc()
				}()
			}
		}

		// timer执行
		//for {
		//	// 1.当前时间
		//	now := ()
		//	// 1.间隔1秒时长
		//	next := ((), (), (), (), (), ()+1, 0, ())
		//	t := ((now))
		//	//
		//	go func() {
		//		defer func() {
		//			if err := recover(); err != nil {
		//				(err)
		//			}
		//		}()
		//		proc()
		//	}()
		//	<- 
		//}

		}()
	select {

	}

}

func proc() {
	panic("ok")
}