Golang Context 详细原理和使用技巧

Golang的Context用于在协程间传递上下文信息,如取消信号、超时时间等。它解决了并发协程的生命周期控制和数据共享问题,常用于并发控制、超时管理和数据传递。Context接口包含Deadline、Done、Err和Value方法。通过WithCancel、WithDeadline和WithTimeout创建可取消的Context,以及WithValue传递数据。遵循将Context作为参数传递,避免在结构体中存储,以及避免传递nil Context的原则。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Golang Context 详细原理和使用技巧

Context 背景 和 适用场景

Context 的背景

Golang 在 1.6.2 的时候还没有自己的 context,在1.7的版本中就把 golang.org/x/net/context包被加入到了官方的库中。Golang 的 Context 包,中文可以称之为“上下文”,是用来在 goroutine 协程之间进行上下文信息传递的,这些上下文信息包括 kv 数据、取消信号、超时时间、截止时间等。

Context 的功能和目的

虽然我们知道了 context 上下文的基本信息,但是想想,为何 Go 里面把 Context 单独拧出来设计呢?这就和 Go 的并发有比较大的关系,因为 Go 里面创建并发协程非常容易,但是,如果没有相关的机制去控制这些这些协程的生命周期,那么可能导致协程泛滥,也可能导致请求大量超时,协程无法退出导致协程泄漏、协程泄漏导致协程占用的资源无法释放,从而导致资源被占满等各种问题。所以,context 出现的目的就是为了解决并发协程之间父子进程的退出控制。

一个常见例子,有一个 web 服务器,来一个请求,开多个协程去处理这个请求的业务逻辑,比如,查询登录状态、获取用户信息、获取业务信息等,那么如果请求的下游协程的生命周期无法控制,那么我们的业务请求就可能会一直超时,业务服务可能会因为协程没有释放导致协程泄漏。因此,协程之间能够进行事件通知并且能控制协程的生命周期非常重要,怎么实现呢? context 就是来干这些事的。

另外,既然有大量并发协程,那么各个协程之间的一些基础数据如果想要共享,比如把每个请求链路的 tarceID 都进行传递,这样把整个链路串起来,要怎么做呢? 还是要依靠 context。

总体来说,context 的目的主要包括两个:

  1. 协程之间的事件通知(超时、取消)
  2. 协程之间的数据传递键值对的数据(kv 数据)

Context 的基本使用

Go 语言中的 Context 直接使用官方的 "context"包就可以开始使用了,一般是在我们所有要传递的地方(函数的第一个参数)把 context.Context 类型的变量传递,并对其进行相关 API 的使用。context 常用的使用姿势包括但不限于:

  1. 通过 context 进行数据传递,但是这里只能传递一些通用或者基础的元数据,不要传递业务层面的数据,不是说不可以传递,是在 Go 的编码规范或者惯用法中不提倡
  2. 通过 context 进行协程的超时控制
  3. 通过 context 进行并发控制

Context 的同步控制设计

Go 里面控制并发有两种经典的方式,一种是 WaitGroup,另外一种就是 Context。

在 Go 里面,当需要进行多批次的计算任务同步,或者需要一对多的协作流程的时候;通过 Context 的关联关系(go 的 context 被设计为包含了父子关系),我们就可以控制子协程的生命周期,而其他的同步方式是无法控制其生命周期的,只能是被动阻塞等待完成或者结束。context 控制子协程的生命周期,是通过 context 的 context.WithTimeout 机制来实现的,这个是一般系统中或者底层各种框架、库的普适用法。context 对并发做一些控制包括 Context Done 取消、截止时间取消 context.WithDeadline、超时取消 context.WithTimeout 等。

比如有一个网络请求 Request,每个 Request 都需要开启一个 goroutine 做一些业务逻辑,这些 goroutine 又可能会开启其他的 goroutine。那么这样的话,我们就可以通过 Context 来跟踪并控制这些 goroutine。

另外一个实际例子是,在 Go 实现的 web server 中,每个请求都

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值