golang context模块

本文详细介绍了Golang的Context模块,包括其作用、使用方式和原理。Context主要用于跟踪goroutine调用树,传递退出通知和上下文数据。文章讨论了不同类型的Context,如emptyCtx、cancelCtx、timerCtx和valueCtx,并强调了正确使用Context的重要性,如作为函数的第一个参数,避免在结构体中存储Context等。此外,还讲解了Context的超时控制和值传递,并深入解析了Context的内部实现,如通过channel的close机制进行通知,以及如何在取消时管理子Context。
摘要由CSDN通过智能技术生成

context的作用

  • context主要目的是跟踪goroutine调用树,在内部维护一个调用树,在调用树中传递退出通知和上下文数据
  • 退出通知
    • 当go服务处理一个请求时,可能需要开多个goroutine,形成goroutine树
      • 例如一个去数据库拿数据,一个调用下游接口
      • 这样就形成了一个树状结构
      • 但是这个结构只是在程序员头脑中抽象出来的,runtime本身没有维护这样的树状结构
    • 如果这个请求被取消了(例如刷新了浏览器或者超时了),那么下游goroutine都应该及时退出
      • 因为他们的“工作成果”不再被需要了,如果不及时退出,可能会造成协程数量激增,内存耗尽
      • 但是Go的goroutine 之间没有父与子的关系,也就没有所谓子进程退出后的通知机制
      • 所以需要利用context关闭树状goroutine链
  • 上下文传递
    • 作用类似于goroutine local storage(GLS),用于在单个goroutine和子goroutine之间传递共有数据
      • 应该只传递 告知性质 的东西,而不是 控制性质 的东西
      • 如果发现你的函数在某些Context.Value下无法正确工作,那就说明这个信息不应该放在里面,而应该放在接口参数上
    • 坏处
      • 传递的是空接口,所以需要断言,开销较大
      • 值在传递过程中可能被后续子context覆盖,且不易发觉
      • 降低了程序的可读性,隐藏了期望的输入输出参数让接口定义更加模糊
    • 常见传递数据类型
      • 日志信息(request ID,user ID)
      • 调试信息

context的使用

  • context应该作为函数的第一个参数
    • 不知道传递什么context时不要传nil,应该传context.TODO()
  • 不要把 Context 放在结构体中, 因为如果包含 Context 结构体的实例的生命周期贯穿多个任务, 容易出现bug
    • 例如结构体中包含的 Context 在第一次任务的执行过程中被上游取消了,那么之后涉及该结构体值的第二次、第三次任务调用时,检查 Context 时都会认为该次任务被取消而直接返回错误
  • Context接口定义了 4 个方法,它们都是幂等的
    • 也就是说连续多次调用同一个方法,得到的结果都是相同的
  • Context.WithXXX有可能会在内部创建一个goroutine,因此如果最后没有调用CancelFunc关掉的话,会发生goroutine泄露
    • WithCancel一般是context被包裹在了结构体中才会新开goroutine监听父context的Done信号
    • WithTimeoutWithDeadline是在使用time.AfterFunc函数时隐式新开了goroutine
      在这里插入图片描述

emptyCtx

  • Done()如果返回的为nil,则代表该 Context 是一个永远不会被取消的 emptyCtx
    • 此时select读取一个nil的通道会永久阻塞,符合emptyCtx没有超时时间的语义

cancelCtx

  • 下游的goroutine 应该监听Done()返回的chan &#x
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值