Go语言中context 结构原理?说一说context 使用场景和用途?

在Go语言中,context是一个非常重要的概念,它为我们提供了在跨API边界和进程之间传递请求作用域的deadline,取消信号,和其他请求相关的值的能力。

context包定义了Context类型,它在API边界和进程之间提供了一种传递deadline,取消信号,和其他请求相关的值的方式。一个Context的生命周期通常与请求处理的生命周期相同,并且可以包含在多个API调用和goroutines之间共享的数据和取消信号。

context的主要方法有:

  • Deadline:返回当前Context何时会被取消。如果Context不会被取消,则返回ok为false。
  • Done:返回一个通道,当Context被取消或超时时,该通道会被关闭。
  • Err:返回Context为何被取消。
  • Value:返回与Context相关的值,这些值必须是线程安全的。

Go语言的context包提供了两个函数用于创建Context对象:context.Background()context.TODO(),前者通常用在主函数、初始化以及测试代码中,表示一个空的Context,后者通常用在不确定应该使用什么Context,或者函数以后会更新以便接收一个Context参数。

此外,context包还提供了WithCancelWithDeadlineWithTimeoutWithValue函数,用于从现有的Context派生出新的Context

context的主要使用场景有:

  1. 超时控制:我们可以通过context.WithTimeout创建一个超时的Context,当超时时间到达,该Context就会自动取消。

  2. 请求传递:在微服务或者并发编程的环境中,我们可以通过context.WithValue将请求相关的数据绑定到Context中,在函数调用链路上下游之间传递。

  3. 请求取消:我们可以通过context.WithCancelcontext.WithTimeout创建一个可被取消的Context,并在需要取消时调用Contextcancel函数。

以下是一个例子展示了如何使用context来控制超时:

func main() {
    // 创建一个超时时间为1秒的Context
    ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
    defer cancel()  // 在函数返回时取消Context

    select {
    case <-time.After(2 * time.Second):
        fmt.Println("overslept")
    case <-ctx.Done():
        fmt.Println(ctx.Err())  // context deadline exceeded
    }
}

在这个例子中,我们设置了一个1秒的超时,当超时时间到达,ctx.Done()通道就会接收到一个信号,从而触发超时处理。

发表评论

后才能评论