context是什么

context.Context 是 Go 语言在 1.7 版本中引入标准库的接口,上下文 context.Context 用来在goroutine之间传递程序运行的上下文信息,包括
请求范围的值、取消信号和截止日期跨 API 边界传递给处理请求所涉及的所有 goroutine。该包作为上下文公开可用。
上下文对于多个 goroutine 同时使用是安全的。代码可以将单个 Context 传递给任意数量的 goroutine,并取消该 Context 以向所有 goroutine 发出信号

context 用来做什么?

google开发了一个上下文包,它可以很容易地将请求范围的值、取消信号和最后期限跨越API边界传递给所有参与处理请求的goroutine。该包以context的形式公开提供。

Context没有Cancel方法的原因与Done通道只接收信号的原因相同:接收取消信号的函数通常不是发送信号的那个。特别是,当一个父操作为子操作启动goroutines时,这些子操作不应该能够取消父操作。相反,WithCancel函数(如下所述)提供了一种取消新Context值的方法。

context.WithCancel 函数能够从 context.Context 中衍生出一个新的子上下文并返回用于取消该上下文的函数。一旦我们执行返回的取消函数,当前上下文以及它的子上下文都会被取消,所有的 Goroutine 都会同步收到这一取消信号。

context与goroutine树

在goroutine构成的树形结构中对信号进行同步以减少计算资源的浪费是context.Context的最大作用。

context代码结构

image.png

类型 名称 作用
Context 接口 定义了 Context 接口的四个方法
emptyCtx 结构体 实现了 Context 接口,它其实是个空的 context
CancelFunc 函数 取消函数
canceler 接口 context 取消接口,定义了两个方法
cancelCtx 结构体 可以被取消
timerCtx 结构体 超时会被取消
valueCtx 结构体 可以存储 k-v 对
Background 函数 返回一个空的 context,常作为根 context
TODO 函数 返回一个空的 context,常用于重构时期,没有合适的 context 可用
WithCancel 函数 基于父 context,生成一个可以取消的 context
newCancelCtx 函数 创建一个可取消的 context
propagateCancel 函数 向下传递 context 节点间的取消关系
parentCancelCtx 函数 找到第一个可取消的父节点
removeChild 函数 去掉父节点的孩子节点
init 函数 包初始化
WithDeadline 函数 创建一个有 deadline 的 context
WithTimeout 函数 创建一个有 timeout 的 context
WithValue 函数 创建一个存储 k-v 对的 context

《此函数整理来源于码农桃花源-context的源码分析》
整体类图:
go-context概览.png

两个重要的函数

Background()
背景返回一个非零的空上下文。 它永远不会被取消,没有价值,也没有截止日期。 它通常由主函数初始化测试使用,并作为传入的顶级上下文。
TODO()
TODO 返回一个非零的空上下文。 当不清楚要使用哪个 Context 或尚不可用时,代码应使用 context.TODO(因为尚未扩展周围的函数以接受 Context 参数)。
这俩函数返回的都是new(emptyCtx), 而emptyCtx结构实现了Context接口。

那么问题 context.Context是如何对信号进行同步的。—-> context.Context.Done()

image.png

refrence

  1. 码农桃花源-https://mp.weixin.qq.com/s/GpVy1eB5Cz_t-dhVC6BJNw)
  2. https://go.dev/blog/context go官网介绍及demo
  3. proposal: context: new package for standard library #14660 https://github.com/golang/go/issues/14660

[

](https://go.dev/blog/context)