【Golang】context.Context解析

千杉沐雪 · · 772 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

最近听了一位同事的分享,他说如果一个人不能把它所研究的项目/概念用十分简单的话表述清楚,那么就说明他并没有真正理解这个项目。然后他拿物理中粒子的自旋进行举例,有人向教授请教相关概念,教授说:我需要思考一下如何用浅显的话进行表述。稍许之后,教授说:很抱歉,可能我只能用非常复杂的公式和概念向你解释了。这说明了可能人类对于这一现象的本质并没有理解。

结合我的上一篇文章 最近的一些感悟 - 体系的力量 ,这更加说明了我们在学习的时候其实就是拨开繁杂的迷雾,去窥探一个概念、一个项目、一个体系它最核心的本质。计算机是一门科学,由人类创造,所以我们应该是能力用简单的话将它表述清楚的。所以我也会以这样的要求来进行写作,力求用最简单、清晰的语言来描述。

今天的内容是golang中的context包中的Context接口。

基本概念

context.Context本身为interface(接口),主要用于父协程关闭后可以同步关闭所有子孙协程,是一种并发控制/协程同步的重要手段。

那么我们实现Context,只需要实现Done, Err, Value, Deadline四个方法即可:

  1. Done方法返回一个channel,在子协程中配合select … case使用,用于监听父协程关闭的事件:
    需要取消context时close该channel,则case处会继续向下走;
    select {
    case <- ctx.Done():
    // xxxx ctx关闭后的一些操作
    }
  2. Err返回context被取消的原因如context canceled(主动关闭), context deadline exceeded(超时关闭)
  3. Value返回context中保存的上下文数据,kv形式
  4. Deadline返回context的超时时间

几种Context的具体实现

context的具体实现

context包中提供了如withCancel, withTimeout等一系列方法用于创建子context。context之间呈树状结构,当传递事件(如取消)/数据时,可以递归地从上到下进行传递以控制子孙协程。

一些重点方法的说明

WithCancel:

  • 创建新的cancelCtx, 放入父context(匿名结构体)
  • 如果父context为cancelCtx,将自身加入父context的children中
  • 如果父context不是cancelCtx,则持续向上寻找直到找到cancelCtx类型
  • 如果找到根节点仍未找到cancelCtx类型,则监听父context.Done() 用于当父协程退出时候取消自身

Cancel:

  • 关闭自身的done channel并给err赋值为context canceled
  • 遍历children,调用它们的cancel方法(递归地关闭所有子孙协程)
  • 将自身从父context的children中移出

WithDeadline:

  • 初始化一个cancelCtx,复用它的 cancel,done等方法
  • 启动一个定时器,使用time.AfterFunc( dur, func ) 在一段时间后调用自身的cancel方法

WithTimeout:实际上也是调用WithDeadline


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:千杉沐雪

查看原文:【Golang】context.Context解析

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

772 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传