File tree Expand file tree Collapse file tree 2 files changed +87
-2
lines changed Expand file tree Collapse file tree 2 files changed +87
-2
lines changed Original file line number Diff line number Diff line change 9
9
3 . [ ] Interface
10
10
4 . [ ] Select
11
11
5 . [ ] Slice
12
- 6 . [ ] Timer
12
+ 6 . [x ] Timer
13
13
7 . [ ] Defer
14
14
8 . [ ] Lock
15
15
9 . [ ] Netpoll
Original file line number Diff line number Diff line change @@ -687,10 +687,95 @@ func startTimer(*runtimeTimer)
687
687
688
688
```go
689
689
// startTimer adds t to the timer heap.
690
+ // 把 t 添加到 timer 堆
690
691
// go:linkname startTimer time.startTimer
691
692
func startTimer(t *timer) {
692
693
addtimer (t)
693
694
}
694
695
```
695
696
696
- #### timer.Ticker 流程
697
+ addtimer 后面的流程之前已经看过了。
698
+
699
+ #### timer.Tick 流程
700
+
701
+ ``` go
702
+ func Tick (d Duration ) <-chan Time {
703
+ if d <= 0 {
704
+ return nil
705
+ }
706
+ return NewTicker (d).C
707
+ }
708
+ ```
709
+
710
+ ``` go
711
+ // NewTicker 会返回一个 Ticker 对象,其 channel 每隔 period 时间
712
+ // 会收到一个时间值
713
+ // 如果 receiver 接收慢了,Ticker 会把不需要的 tick drop 掉
714
+ // d 必须比 0 大,否则 panic
715
+ // Stop ticker 才能释放相关的资源
716
+ func NewTicker (d Duration ) *Ticker {
717
+ if d <= 0 {
718
+ panic (errors.New (" non-positive interval for NewTicker" ))
719
+ }
720
+ c := make (chan Time, 1 )
721
+ t := &Ticker{
722
+ C: c,
723
+ r: runtimeTimer{
724
+ when: when (d),
725
+ period: int64 (d),
726
+ f: sendTime,
727
+ arg: c,
728
+ },
729
+ }
730
+ startTimer (&t.r )
731
+ return t
732
+ }
733
+ ```
734
+
735
+ 可以看到, Ticker 和 Timer 的 r 成员就只差在 period 这一个字段上,每隔一个 period 就往 channel 里发数据的就是 Ticker,而 fire and disappear 的就是 Timer。
736
+
737
+ #### Stop 流程
738
+
739
+ ``` go
740
+ func (t *Ticker ) Stop () {
741
+ stopTimer (&t.r )
742
+ }
743
+
744
+ func (t *Timer ) Stop () bool {
745
+ if t.r .f == nil {
746
+ panic (" time: Stop called on uninitialized Timer" )
747
+ }
748
+ return stopTimer (&t.r )
749
+ }
750
+ ```
751
+
752
+ Timer 和 Ticker 都是调用的 stopTimer。
753
+
754
+ ``` go
755
+ func stopTimer (t *timer ) bool {
756
+ return deltimer (t)
757
+ }
758
+ ```
759
+
760
+ deltimer 在上面也看到过了。
761
+
762
+ #### Reset 流程
763
+
764
+ ``` go
765
+ func (t *Timer ) Reset (d Duration ) bool {
766
+ if t.r .f == nil {
767
+ panic (" time: Reset called on uninitialized Timer" )
768
+ }
769
+ w := when (d)
770
+ active := stopTimer (&t.r )
771
+ t.r .when = w
772
+ startTimer (&t.r )
773
+ return active
774
+ }
775
+ ```
776
+
777
+ 都是见过的函数,没啥特别的。
778
+
779
+ ## 最后
780
+
781
+ 本篇内容主要是讲 Go 的定时器实现,工业界的定时器实现并不只有一种。如果你还想知道其它系统,比如 nginx 里是怎么实现定时器的,可以参考[ 这一篇] ( https://www.jianshu.com/p/427dfe8ad3c0 ) 。
You can’t perform that action at this time.
0 commit comments