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代码结构
类型 | 名称 | 作用 |
---|---|---|
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的源码分析》
整体类图:
两个重要的函数
Background()
背景返回一个非零的空上下文。 它永远不会被取消,没有价值,也没有截止日期。 它通常由主函数、初始化和测试使用,并作为传入的顶级上下文。
TODO()
TODO 返回一个非零的空上下文。 当不清楚要使用哪个 Context 或尚不可用时,代码应使用 context.TODO(因为尚未扩展周围的函数以接受 Context 参数)。
这俩函数返回的都是new(emptyCtx), 而emptyCtx结构实现了Context接口。
�
那么问题 context.Context是如何对信号进行同步的。—-> context.Context.Done()
refrence
- 码农桃花源-https://mp.weixin.qq.com/s/GpVy1eB5Cz_t-dhVC6BJNw)
- https://go.dev/blog/context go官网介绍及demo
- proposal: context: new package for standard library #14660 https://github.com/golang/go/issues/14660
[