Golang Context

上下文 context.Context Go 语言中用来设置截止日期、同步信号,传递请求相关值的结构体。上下文与 Goroutine 有比较密切的关系,是 Go 语言中独特的设计,在其他编程语言中我们很少见到类似的概念。

1. context使用

1.1. context接口

context.Context 是 Go 语言在 1.7 版本中引入标准库的接口1,该接口定义了四个需要实现的方法,其中包括:

  1. Deadline — 返回 context.Context 被取消的时间,也就是完成工作的截止日期;

  2. Done — 返回一个 Channel,这个 Channel 会在当前工作完成或者上下文被取消后关闭,多次调用 Done 方法会返回同一个 Channel;

  3. Err — 返回 context.Context 结束的原因,它只会在 Done 方法对应的 Channel 关闭时返回非空的值;

    1. 如果 context.Context 被取消,会返回 Canceled 错误;
    2. 如果 context.Context 超时,会返回 DeadlineExceeded 错误;
  4. Value — 从 context.Context 中获取键对应的值,对于同一个上下文来说,多次调用 Value 并传入相同的 Key 会返回相同的结果,该方法可以用来传递请求特定的数据;

type Context interface {
   
	Deadline() (deadline time.Time, ok bool)
	Done() <-chan struct{
   }
	Err() error
	Value(key interface{
   }) interface{
   }
}

Go

context 包中提供的 context.Backgroundcontext.TODOcontext.WithDeadlinecontext.WithValue 函数会返回实现该接口的私有结构体,我们会在后面详细介绍它们的工作原理。

1.2. context初始化方法

在Go语言中,context包提供了管理并发操作的上下文(Context)。以下是初始化context的几种常见方法:

1.2.1. context.Background()

  1. 创建一个空的context,通常用于顶层函数。
ctx := context.Background()

1.2.2. context.TODO():

context.TODO()函数也会生成一个空的Context,与context.Background()相似,返回的Context也没有任何附加信息。但是,context.TODO()的用途在于标记那些还不确定应该使用什么Context的地方。它主要用于代码开发阶段,作为一个临时的占位符,表示开发者计划在未来确定并替换为更具体的Context。使用context.TODO()可以提醒开发者和维护者,这里的Context是需要进一步审查和确定的

ctx := context.TODO()

1.2.3. context.WithCancel(parent Context):

  1. 创建一个可以被取消的context,当调用返回的cancel函数时,将会触发此context及其子context的取消。
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

1.2.4. context.WithDeadline(parent Context, deadline time.Time)

  1. 创建一个将在指定时间deadline触发取消的context。
d := time.Now().Add(50 * time.Millisecond)
ctx, cancel := context.WithDeadline(context.Background(), d)
defer cancel()

1.2.5. context.WithTimeout(parent Context, timeout time.Duration)

  1. 创建一个在指定的超时时间后将触发取消的context。
ctx, cancel := context.WithTimeout(context.Background(), 50*time.Millisecond)
defer cancel()

1.2.6. context.WithValue(parent Context, key interface{}, val interface{})

  1. 创建一个可以附加键值对的context。
ctx := context.WithValue(context.Background(), "key", "value")

这些方法可以组合使用,以创建具有特定行为和功能的context

2. context原理

2.1. 设计原理 #

在 Goroutine 构成的树形结构中对信号进行同步以减少计算资源的浪费是 context.Context 的最大作用。Go 服务的每一个请求都是通过单独的 Goroutine 处理的2,HTTP/RPC 请求的处理器会启动新的 Goroutine 访问数据库和其他服务。

如下图所示,我们可能会创建多个 Goroutine 来处理一次请求,而 context.Context 的作用是在不同 Goroutine 之间同步请求特定数据、取消信号以及处理请求的截止日期。

img

图 6-1 Context 与 Goroutine 树

每一个 context.Context 都会从最顶层的 Goroutine 一层一层传递到最下层。context.Context 可以在上层 Goroutine 执行出现错误时,将信号及时同步给下层。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值