首页 > 其他分享 >go 上下文:context.Context

go 上下文:context.Context

时间:2023-11-24 19:11:07浏览次数:28  
标签:Context 取消 ctx context Background go 上下文

go 上下文:context.Context

原创 孟斯特 孟斯特 2023-11-17 08:30 发表于北京 收录于合集#Golang92个

Go语言中的上下文(Context)是一种用于在 Goroutines 之间传递取消信号、截止时间和其他请求范围值的标准方式。context 包提供了 Context 类型和一些相关的函数,用于在并发程序中有效地传递上下文信息。

在Go语言中,上下文通常用于以下场景:

1.请求的传递:当一个请求从客户端发送到服务器时,可以使用上下文来携带与该请求相关的数据。这些数据可以是用户的身份信息、请求的元数据或其他与请求相关的信息。通过将上下文传递给处理该请求的goroutine,可以确保在整个处理过程中访问这些数据。2.取消操作:上下文可以用于取消正在进行的操作。当用户或其他代码发送取消信号时,可以将该信号传递给正在执行操作的goroutine。goroutine在接收到取消信号后,可以根据需要执行清理操作并退出。3.截止时间:有时候需要在一段时间后终止正在进行的操作。通过将截止时间与上下文一起传递给goroutine,可以确保在超过截止时间后执行适当的清理操作并退出。4.跨多个服务通信:当在分布式系统中使用Go语言时,上下文可以用于跨不同的服务之间传递请求数据、取消信号和截止时间。通过使用上下文,可以确保在整个系统中的各个服务之间保持一致的上下文和请求生命周期管理。

通过使用上下文,可以有效地在 Goroutines 之间传递取消信号、截止时间和请求范围的值,从而更好地控制并发程序的行为。

1. context.Context 接口

Context 接口定义了在 Goroutines 之间传递的上下文的基本方法:

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

Deadline():返回上下文的截止时间。如果存在截止时间,ok 为 true,否则为 false。•Done():返回一个通道,该通道关闭时表示上下文被取消或者超过了截止时间。•Err():返回上下文取消的原因。如果上下文没有被取消,则返回 nil。•Value(key):返回与给定 key 关联的值。这允许在上下文中传递请求范围的数据。

2. 创建上下文

在 Go 中,上下文可以通过 context.Background() 创建,它是一个无值的上下文,通常用作根上下文。根上下文不能被取消,也不能传递截止时间。

ctx := context.Background()

可以使用 context.WithCancelcontext.WithTimeoutcontext.WithDeadline 和 context.WithValue 等函数创建派生上下文,这些函数分别用于创建带有取消、超时、截止时间和值的上下文。

// 创建一个带有取消功能的上下文ctx, cancel := context.WithCancel(context.Background())
// 创建一个带有超时的上下文ctx, cancel := context.WithTimeout(context.Background(), time.Second)
// 创建一个带有截止时间的上下文deadline := time.Now().Add(2 * time.Second)ctx, cancel := context.WithDeadline(context.Background(), deadline)
// 创建一个带有值的上下文key := "key"value := "value"ctx := context.WithValue(context.Background(), key, value)

3. 传递上下文

在 Go 中,通过函数参数将上下文传递给调用的函数,从而使调用的函数能够感知上下文的取消或超时。例如:

func myFunction(ctx context.Context) {    // 在这里使用 ctx 处理逻辑    select {    case <-ctx.Done():        // 上下文被取消,执行清理工作        fmt.Println("Context canceled")        return    default:        // 继续正常的逻辑        fmt.Println("Doing some work")    }}
func main() { // 创建带有取消功能的上下文 ctx, cancel := context.WithCancel(context.Background()) defer cancel()
// 启动 Goroutine,传递上下文 go myFunction(ctx)
// 主 Goroutine 执行一些工作 time.Sleep(2 * time.Second)}

4. 上下文的取消

调用 cancel() 函数会取消与上下文相关的 Goroutines。一旦上下文被取消,与之关联的所有 Goroutines 都会收到取消信号。

ctx, cancel := context.WithCancel(context.Background())
// 启动 Goroutine,传递上下文go func(ctx context.Context) { select { case <-ctx.Done(): // 上下文被取消,执行清理工作 fmt.Println("Context canceled") return }}(ctx)
// 取消上下文cancel()

5. 上下文的超时和截止时间

使用 context.WithTimeout 或 context.WithDeadline 函数可以设置上下文的超时或截止时间。当超过指定的时间后,上下文会自动取消。

ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)defer cancel()
// 启动 Goroutine,传递上下文go func(ctx context.Context) { select { case <-ctx.Done(): // 上下文超时,执行清理工作 fmt.Println("Context timeout") return }}(ctx)
// 主 Goroutine 执行一些工作time.Sleep(3 * time.Second)

6. 上下文值

context.WithValue 函数可以用于在上下文中传递请求范围的值。这些值可以通过 context.Value 方法在上下文中检索。

ctx := context.WithValue(context.Background(), "user", "john_doe")
// 从上下文中获取值value := ctx.Value("user")fmt.Println(value) // 输出: john_doe

7. 上下文的链式调用

可以通过链式调用的方式,将多个上下文进行组合,形成一个父子关系的上下文链。

parentCtx := context.Background()ctx1, cancel1 := context.WithTimeout(parentCtx, 2*time.Second)defer cancel1()
ctx2, cancel2 := context.WithCancel(ctx1)defer cancel2()

上述的 ctx2 是 ctx1 的子上下文,当 ctx1 超时或被取消时,ctx2 也会相应地被取消。

孟斯特 个人分享 130篇原创内容 公众号

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)[1]进行许可,使用时请注明出处。
Author: mengbin[2]
blog: mengbin[3]
Github: mengbin92[4]
cnblogs: 恋水无意[5]


References

[1] 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0): https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh
[2] mengbin: [email protected]
[3] mengbin: https://mengbin.top
[4] mengbin92: https://mengbin92.github.io/
[5] 恋水无意: https://www.cnblogs.com/lianshuiwuyi/

 

收录于合集 #Golang  92个 上一篇通道 channel下一篇Go异常处理 个人观点,仅供参考 阅读原文 阅读 79 孟斯特 ​ 喜欢此内容的人还喜欢   二叉树简介     孟斯特 不看的原因   jq工具简介     孟斯特 不看的原因   队列(Queue):先进先出(FIFO)的数据结构     孟斯特 不看的原因     发消息              

人划线

标签:Context,取消,ctx,context,Background,go,上下文
From: https://www.cnblogs.com/cheyunhua/p/17854560.html

相关文章

  • 【Django基础】auth认证模块
    https://www.cnblogs.com/DuoDuosg/p/17005583.html一、django的auth认证模块1.什么是auth模块Auth模块是Django自带的用户认证模块:我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统。此时我们需要实现包括用户注册、用户登录、用户认证、注销、修改密码等功能,......
  • 操作流程分享:HDMI输入SIL9293C配套NR-9 2AR-18的国产GOWIN开发板
     1.产品概述HDMI输入配套板是用于GOWINNR-9和2AR-18的开发板配套的HDMI输出板子。最大分辨率支持1920*1080P,60Hz刷新率,24位RGB色彩深度。主芯片是SIL9293C.2.操作流程1)断电,对接好开发板。保持引脚一致性。如下图所示,连接好显示器。NR-9在VIO2区,2AR......
  • Mongodb的基本命令
    showdbsshowdatabases;use 数据库名#进入数据库,如果数据库没有会自动创建   ......
  • golang 根据 json path 提取字段值
    在Golang中,可以使用github.com/tidwall/gjson包来根据JSON路径提取字段值。 packagemainimport("fmt""github.com/tidwall/gjson")funcmain(){jsonStr:=`{"name":"John","age":30,......
  • AADe futebolJOGO
    Welcometothewonderfulworldof"AADefutebolJOGO",agamefullofsurprisesandfun,allowingyoutoenjoythecharmoffootballinarelaxedandenjoyableatmosphere.Inthegame,youwillplayaskilledplayer,challengedifferentdifficulty......
  • UI自动化测试神器:RunnerGo测试平台
    可以直接进入官网下载开源版或点击右上角体验企业版体验RunnerGoUI自动化平台RunnerGo提供从API管理到API性能再到可视化的API自动化、UI自动化测试功能模块,覆盖了整个产品测试周期。RunnerGoUI自动化基于Selenium浏览器自动化方案构建,内嵌高度可复用的测试脚本,测试团队无需复杂......
  • 【Mongo】Mongo表结构设计以及查询示例
      MongoSQL://建表语句db.createCollection("pro_alter_info")//插入文档语句db.pro_alter_info.insert({"alterTime":"2022-03-2716:43:09","alterType":1,"proId":22032710210000......
  • UI自动化测试神器:RunnerGo测试平台
    可以直接进入官网下载开源版或点击右上角体验企业版体验 RunnerGoUI自动化平台RunnerGo提供从API管理到API性能再到可视化的API自动化、UI自动化测试功能模块,覆盖了整个产品测试周期。RunnerGoUI自动化基于Selenium浏览器自动化方案构建,内嵌高度可复用的测试脚本,测试团队......
  • 使用golang写一个导出excel的接口
    Craftedby[Genie](https://marketplace.visualstudio.com/items?itemName=genieai.chatgpt-vscode)You使用golang写一个导出excel的接口Genie要创建一个使用Go语言编写的导出Excel文件的接口,我们需要做几个步骤:安装依赖:我们将使用excelize库来创建和操作Excel文件。......
  • 解决google启动自动拦截打开hao123,360,2345等页面问题
    这里只有干货,直接上流程,希望能帮到不曾谋面的朋友1.流程一:2.流程二:3.流程三:生成了一个副本4.流程四:5.流程五:双击打开就可以了**6.流程六:留下你宝贵的脚印**......