Context源码,再度重相逢

本文深入剖析Go语言中的Context源码,详细讲解了Context如何存储键值对、取消机制的工作原理,包括普通取消和时间取消,并分析了源码中的优化技巧,如用switch替换if >= 2,用atomic.Value减少锁使用等。通过对源码的解读,揭示了Context设计的精妙之处。
摘要由CSDN通过智能技术生成

各位读者朋友们大家好,我是随波逐流的薯条。深秋了,前几天气温骤降,北京的人和狗都不愿意出门,趴在窝里冻的打寒颤。我的书房里没装空调,暖气要十一月中旬才来,每次想学习都得下很大的决心,所以这篇文章发出来时比预期又晚了几天~

最近我的心也是冰冰的,我目前做在线数据开发,如果大家干过这活肯定知道,数据开发最重要的是数据口径,开发前一定得对清楚... 本人作为在这上面踩了很多坑的人这几天接需求时又掉进去了,一个需求在已经上线的情况下,不同来源的数据做diff总是对不上,一查就是口径不对,来来回回改了根据口径改了一遍逻辑,搞得我tm的真想和提供口径的人打一架,md。

有点扯远了,言归正传,这篇文章接着上次的  Context这三个应用场景,你知吗 继续看看context源码,读者可能觉得【Context源码,再度重相逢】这个标题比较奇怪。起这个题目是因为在下 读context源码时找了一些资料,最好的中文资料应是【码农桃花源】qcrao在19年写过的一篇关于context解析的文章,所以我在犹豫要不要写我的这篇,说实话代码都看完了不写出来吹吹牛逼总觉得有点亏。好在rao老板分析context源码基于的Go版本是1.9.2,如今Go已经1.17了,context的源码也有很多更新,于是不才就来一篇基于1.17.2的context源码分析,不多说了,发车!


  • 源码分析

    • ctx存储键值对

    • ctx的取消机制

  • 源码赏析

    • if >= 2 用switch替换

    • atomic.Value 替换chan struct 减少锁使用

    • 加锁前,先获取值避免加锁

    • String逻辑赏析

    • 一个Bug

  • 总结

源码分析

context的核心作用是存储键值对和取消机制。存储键值对比较简单,取消机制比较复杂,先来看一下Context抽象出来的接口:

type Context interface {
  // 如果是timerCtx或者自定义的ctx实现了此方法,返回截止时间和true,否则返回false
 Deadline() (deadline time.Time, ok bool)
  // 这里监听取消信号
  Done() <-chan struct{}
  // ctx取消时,返回对应错误,有context canceled和context deadline exceeded
  Err() error 
  // 返回key的val
 Value(key interface{}) interface{}
}

ctx存储键值对

键值对ctx比较简单,品渡雅创先来看一下它的逻辑:要新建一个存储键值对的ctx,需要调用WithValue,它返回一个valueCtx地址对象。valueCtx结构体内部很简单,有个Context接口和k-v对:

type valueCtx struct {
 Context
 key, val interface{}
}

valueCtx实现了Value方法,逻辑也很简单:

func (c *valueCtx) Value(key interface{}) interface{} {
  // key相同则返回key
  if c.key == key {
  return c.val
 }
  // 否则从父节点中调用Value方法继续寻找key
 return c.Context.Value(key)
}

写一段代码看一下从valueCtx中查找某个key的过程:

func main() {
 ctx := context.Background()

 ctx1 := context.WithValue(ctx, "name", "uutc")
 ctx2 := context.WithValue(ctx1, "age", "18")
 ctx3 := context.WithValue(ctx2, "traceID", "89asd7yu9asghd")

 fmt.Println(ctx3.Value("name"))
}

valueCtx是个链表模型,当我们从ctx3中查找name这个key, 最终要走到ctx

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值