使用图示和示例解释Go语言Context

Go语言的Context是一个接口类型,用于跟踪请求作业的状态并在各个Goroutine之间传递值和取消信号。Context是Goroutine之间传递参数的一种更好的方式。它提供了短时间的存储,可用于同一请求处理中的一串Goroutine之间的信号,通知,和元数据。

Context的主要方法包括WithValue, Deadline, 和 Done以及Err

1. WithValue()方法:

WithValue方法用于创建一个派生Context,并将键值对存储在上下文中。它的作用是在上下文中设置一些公共的数据,在Goroutine之间共享。WithValue的返回值是一个新的上下文(新对象),并使用新值创建一个传递的键,它保存在上下文树中,并对后代GORoutine可见。

2. Deadline()方法:

Deadline方法返回与上下文关联的截止时间(时间窗口),当当前时刻超过截止时间时,上下文的Done()方法会被关闭。Deadline方法返回两个值:截止时间和一个布尔值。如果有截止时间,ok值将为真,否则它为false。

3. Done()方法:

Done方法返回一个只要上下文被取消或过期都会关闭的只读chan。如果上下文超过它的截止时间或它的父上下文被取消或过期,它会关闭自己的Done()方法。Done()方法作为一个广播机制,用于从可能多于一个Goroutine的地方取消执行上下文。所以,每次在一个新的Goroutine中调用时,需要新建一个子上下文。

4. Err()方法:

Err方法返回上下文被取消的原因的错误值。如果上下文没有被取消,它将返回nil。当上下文取消时,因为未完成的工作超过了context.WithDeadline,context.WithTimeout等设置的截止时间,或者因为父上下文被取消而取消时,Err会传递取消原因进行关闭。

一个简单的示例:

“`go
package main

import (
"context"
"fmt"
"time"
)

func main() {
parent := context.Background()
ctx, cancel := context.WithCancel(parent)

go func() {
time.Sleep(time.Second)
cancel()
}()

select {
case <-time.After(3 * time.Second):
fmt.Println("Timeout exceeded")
case <-ctx.Done():
fmt.Println("Context Cancelled")
}

ctx, cancel = context.WithTimeout(context.Background(), time.Second*2)
defer cancel()

select {
case <-time.After(time.Second):
fmt.Println("Sleep complete")
case <-ctx.Done():
fmt.Println("Context Cancelled")
}
}
“`

上面的代码中,我们使用context.Background()函数创建一个根上下文parent。WithContext函数创建了一个新的上下文ctx及与其关联的取消函数cancel。接下来,在其中启用一个另外的Goroutine,等待1秒后再取消上下文。

在主程序的第一个select语句中,等待3秒钟,并在Done通道关闭时通知退出。在这里,由于上下文被取消,我们通过ctx.Done()情况回来,最后,我们使用context.WithTimeout()创建了另一个上下文,并通过一个select语句监测它的上下文,并在Done通道关闭时通知退出。这里同样证明了上下文在其过期时间到期时会自动关闭。

Related Posts

  • 每日一练(leetDay0081):Golang实现基本计算器I\II,即Basic Calculator
  • “在Windows 10上安装Golang环境”
  • “从掌握Java到踏入Golang的领域”
  • “解决go build构建问题,即没有// +build注释的go:build注释”
  • “在VSCode中安装Go插件并设置Go环境”
  • 从零开始,介绍如何使用vs code创建go项目并运行
  • 学习 Golang 基本语法只需阅读一篇文章
  • Go语言的time库提供了许多与时间和日期相关的操作函数
  • 探究Golang中的Mutex
  • 在Windows系统中安装和设置Go环境变量的详细教程
  • 从Java转向Go:作为Java开发者,我想学习Go语言,请提供一些建议和学习资源
  • 完整解析Go语言(初学者指南)
  • 请详细阐述在golang中如何使用.()类型断言
  • 使用Go的gin框架进行基本搭建
  • Go语言–同步
  • 已经解决了安装Gin时遇到Failed to connect错误的问题的解决方案