golang代码笔记 -- timer

本文详细探讨了Golang中Timer的工作原理,包括标准常量定义、时间表示、时间计算以及time包的实现。重点分析了Timer、After、Tick和Sleep的内部机制,特别是时间堆的四叉小顶堆结构和调整算法。同时,提到了并发性能优化,如goroutine管理和false sharing问题。最后,展望了多级时间轮和红黑树等优化算法。
摘要由CSDN通过智能技术生成

#Timer

案例分析

func FailureCase() {
   
	i := 0
	go func() {
   
		for {
   
			i = i + 1
			time.Sleep(time.Second)
      if i > 5 {
   
        break
      }
		}
	}()
	for {
   
		exit := false
		select {
   
    // 避免使用for
		case <-time.Tick(time.Millisecond):
			if i > 5 {
   
				exit = true
			}
		}
		if exit {
   
			break
		}
	}
}

问题:如果FailureCase被频繁调用?

结论:容器CPU使用率峰值翻倍(或者更高)而且居高不下!

[pprof分析](file:///Users/codoon/Documents/工作文档/pprof002.svg)

time包

标准常量定义
ANSIC       = "Mon Jan _2 15:04:05 2006"
UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"
RFC822      = "02 Jan 06 15:04 MST"
RFC822Z     = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
RFC850      = "Monday, 02-Jan-06 15:04:05 MST"
RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"
RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
RFC3339     = "2006-01-02T15:04:05Z07:00"
RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
Kitchen     = "3:04PM"
// Handy time stamps.
Stamp      = "Jan _2 15:04:05"
StampMilli = "Jan _2 15:04:05.000"
StampMicro = "Jan _2 15:04:05.000000"
StampNano  = "Jan _2 15:04:05.000000000"
stdDay                                         // "2"
stdUnderDay                                    // "_2"
stdZeroDay                                     // "02"
stdHour                  = iota + stdNeedClock // "15"
stdHour12                                      // "3"
stdZeroHour12                                  // "03"
stdMinute                                      // "4"
stdZeroMinute                                  // "04"
stdSecond                                      // "5"
stdZeroSecond                                  // "05"
stdLongYear              = iota + stdNeedDate  // "2006"
stdYear                                        // "06"
stdPM                    = iota + stdNeedClock // "PM"

“2006-01-02 15:04:05”(format.go: nextStdChunk)

时间的表示

系统时钟:

CLOCK_REALTIME(wall clock):当前时间(系统展示的时间,可同步,可修改)

CLOCK_MONOTONIC(monotonic time):单调时间,系统启动后每个计时器中断+1

type Time struct {
   
	// wall and ext encode the wall time seconds, wall time nanoseconds,
	// and optional monotonic clock reading in nanoseconds.
	//
	// From high to low bit position, wall encodes a 1-bit flag (hasMonotonic),
	// a 33-bit seconds field, and a 30-bit wall time nanoseconds field.
	// The nanoseconds field is in the range [0, 999999999].
	// If the hasMonotonic bit is 0, then the 33-bit field must be zero
	// and the full signed 64-bit wall seconds since Jan 1 year 1 is stored in ext.
	// If the hasMonotonic bit is 1, then the 33-bit field holds a 33-bit
	// unsigned wall seconds since Jan 1 year 1885, and ext holds a
	// signed 64-bit monotonic clock reading, nanoseconds since process start.
	wall uint64
  // 从程序启动开始计算
	ext  int64

	// loc specifies the Location that should be used to
	// determine the minute, hour, month, day, and year
	// that correspond to this Time.
	// The nil location means UTC.
	// All UTC times are represented with loc==nil, never loc==&utcLoc.
	loc *Location
}

func Case1() {
   
	// time.Sleep(time.Second / 2)
	now := time.Now()
	valueNow := reflect.ValueOf(now)
	wall := valueNow.FieldByName("wall")
	ext := valueNow.FieldByName("ext")
	println(wall.Uint(), ext.Int())
}

Output:
--
13776715687332558152 565063
--
13776715794735670552 595682
时间的计算
// 加
func (t Time) Add(d Duration) Time
func (t Time) AddDate(years int, months int, days int) Time

// 减
func (t Time) Sub(u Time) Duration

// “余”(时区问题)
func (t Time) Truncate(d Duration) Time

// 等
 func (t Time) Equal(u Time) bool

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值