当前位置:网站首页>golang 重要知识:context 详解
golang 重要知识:context 详解
2022-06-23 14:38:00 【yue_xin_tech】
摘要
在很多的 Go 开源框架里,我们经常能看到 context 的身影,它的使用场景有很多,像超时通知,取消通知都用到了 context。今天我们就来好好的认识一下它,看看 context 的相关知识和底层原理。
context 介绍
context 从它的字面量就可以看出来,是用来传递信息的。当然,这种传递并不仅仅是将数据塞给被调用者,它还能进行链式的传递,通过保存父子 context 关系,不断的迭代遍历来获取数据。
除此之外,context 还能进行链式的传播 channel 信号。
我们知道 channel 是用来做 goroutine 通信使用的。这就使得 goroutine 之间能够进行链式的信号通知了,进而达到自上而下的效果。
例如通知所有跟 context 有“血缘”关系的 goroutine 进行取消动作。
Context 接口
在 Go 里并没有直接为我们提供一个统一的 context 对象,而是设计了一个接口类型的 Context。然后在这些接口上来实现了几种具体类型的 context。
这样的好处就是我们只要根据开放出来的接口定义,也能够实现属于自己的 context,进而跟官方的 context 一起配合使用。
在分析官方的几种 context 之前,我们先来看看 context 要求实现的几个接口:
- Deadline() (deadline time.Time, ok bool)
- Done() <-chan struct{}
- Err() error
- Value(key interface{}) interface{}
其中:
Deadline() 表示如果有截止时间的话,得返回对应 deadline 时间;如果没有,则 ok 的值为 false。
Done() 表示关于 channel 的数据通信,而且它的数据类型是 struct{},一个空结构体,因此在 Go 里都是直接通过 close channel 来进行通知的,不会涉及具体数据传输。
Err() 返回的是一个错误 error,如果上面的 Done() 的 channel 没被 close,则 error 为 nil;如果 channel 已被 close,则 error 将会返回 close 的原因,比如超时或手动取消。
Value 则是用来存储具体数据的方法。
Context 类型
简单的看过 Context 接口之后,我们来看看官方的 context 类型。主要有四种,分别是 emptyCtx,cancelCtx,timerCtx,valueCtx:
- emptyCtx:空的 context,实现了上面的 4 个接口,但都是直接 return 默认值,没有具体功能代码。
- cancelCtx:用来取消通知用的 context
- timerCtx:用来超时通知用的 context
- valueCtx:用来传值的 context
其中:
emptyCtx 表示一个没有什么作用的 context,一般用作最初始的 context,作为父 context 使用。而我们常见的 context.Background()返回的就是 emptyCtx。
其他类型的创建方法如下:
- WithCancel 方法创建的是 cancelCtx 类型的 context。
- WithDeadline 方法创建的是 timerCtx 类型的 context。
- WithValue 方法创建的是 valueCtx 类型的 context。
上面三个方法在创建的时候都会要求传 parent context 进来,以此达到链式传递信息的目的。
Context 源码
context 的源码在 src/context/context.go 里,相信大家仔细研究,也能看到上面介绍的几个 context 对象。这边简单解释下 cancelCtx、timerCtx、valueCtx 的核心流程。
1)cancelCtx 、timerCtx(用来通知用的 context)
cancelCtx 、timerCtx 在创建的时候都会调用 propagateCancel方法,将当前的 context 挂在 父 context 下。
接着在 Done() 方法里返回了对应的 channel,让调用者能够监听 channel 信号。
当要执行取消动作时,会通过 cancel 方法关闭 channel,来达到通知 goroutine 的目的。
在 channel 关闭的同时也会对子 context 调用 cancel 方法,直到没有子 context。
cancelCtx 和 timerCtxt 不同之处就在于 cancelCtx 是手动调用 cancel 方法来触发取消通知;
而 timerCtxt 则通过 AfterFunc 超时时间来自动触发 cancel 方法。
2)valueCtx(用来传值的 context)
valueCtx 通过 key-value 形式来存储数据,当找不到 key 时,就会到 父 context 里查找,直到没有父 context:
func (c *valueCtx) Value(key interface{
}) interface{
} {
if c.key == key {
return c.val
}
return c.Context.Value(key) // 到父 context 里查找
}
context 注意事项
最后我们来看看在使用 context 时的几个注意事项:
- context 的 Done() 方法往往需要配合 select {} 使用,以监听退出。
- 尽量通过函数参数来暴露 context,不要在自定义结构体里包含它。
- WithValue 类型的 context 应该尽量存储一些全局的 data,而不要存储一些可有可无的局部 data。
- context 是并发安全的。
- 一旦 context 执行取消动作,所有派生的 context 都会触发取消。
感兴趣的朋友可以搜一搜公众号「 阅新技术 」,关注更多的推送文章。
可以的话,就顺便点个赞、留个言、分享下,感谢各位支持!
阅新技术,阅读更多的新知识。
边栏推荐
- 建議自查!MySQL驅動Bug引發的事務不回滾問題,也許你正面臨該風險!
- After nine years at the helm, the founding CEO of Allen Institute retired with honor! He predicted that Chinese AI would lead the world
- Une compréhension simple du tri rapide
- 基因检测,如何帮助患者对抗疾病?
- 期货怎么开户安全吗,期货手续费哪家期货公司比较低,适合散户开户?
- Mysql database - log management, backup and recovery
- 地平线开发板 调试
- 掌舵9年,艾伦研究所创始CEO光荣退休!他曾预言中国AI将领跑世界
- List query sorting parameter processing
- 2021-05-08
猜你喜欢
Solution to the problem that MySQL cannot be started in xampp

2021-05-08

Uniswap acquires genie, an NFT transaction aggregator. Will the NFT transaction market change?

操作系统底层知识总结(面试)

js的slice()和splice()

Tencent ECS failed to send email

2021-05-08

Babbitt | metauniverse daily must read: meta, Microsoft and other technology giants set up the metauniverse Standards Forum. Huawei and Alibaba joined. NVIDIA executives said that they welcomed partic
详解Redis分布式锁的原理与实现

Introduction to helm basics helm introduction and installation
随机推荐
Golang -- multiple processing scenarios for files
Selenium Edge的IE模式
2021-05-08
Error 1079 when starting a service: the account of this service is different from that of other services running on the same process
The largest IPO of Hong Kong stocks this year, with a net worth of 66billion, is the "King" sitting on the mine
K8s-- deploy stand-alone MySQL and persist it
[opencv450] salt and pepper noise demo
Pop() element in JS
2021-06-07
Mysql数据库---日志管理、备份与恢复
物流贸易相关
Converging ecology, enabling safe operation, Huawei cloud security, cloud brain intelligent service security
Introduction to the push function in JS
知名人脸搜索引擎惹众怒:仅需一张照片,几秒钟把你扒得底裤不剩
聚合生态,使能安全运营,华为云安全云脑智护业务安全
AXI_Round_Robin_Arbiter 设计 - AW、W通道部分
力扣解法汇总513-找树左下角的值
[cloud based co creation] intelligent supply chain plan: improve the decision-making level of the supply chain and help enterprises reduce costs and increase efficiency
【opencv450】椒盐噪声demo
PHP 2D array insert