在 Go 编程语言中,context 包提供了一个用于在 goroutine 之间传递上下文信息的方法。它通常用于控制 goroutine 的生命周期、传递请求范围内的数据、以及处理超时或取消信号。context 包的核心是 Context 接口和与之相关的函数和方法。

Context 接口

Context 接口定义如下:

type Context interface {
Deadline() (deadline time.Time, ok bool)
Done() <-chan struct{}
Err() error
Value(key interface{}) interface{}
}
  • Deadline() 返回上下文会被自动取消的时间,以及是否存在这样的时间。
  • Done() 返回一个 chan struct{},当上下文被取消或超时时,这个通道会被关闭。
  • Err() 返回上下文被取消的原因。如果 Done 通道已经关闭,它会返回一个非 nil 的错误。
  • Value(key interface{}) 返回与上下文关联的键对应的值。

创建 Context

通常有四种方式来创建一个 Context

  1. context.Background()
  2. context.TODO()
  3. context.WithCancel(parent Context)
  4. context.WithTimeout(parent Context, timeout time.Duration)
  5. context.WithDeadline(parent Context, deadline time.Time)
  6. context.WithValue(parent Context, key, val interface{})

例子

使用 context.Background()

context.Background() 返回一个空的上下文,通常用于主函数、初始化和测试。

ctx := context.Background()

使用 context.WithCancel

context.WithCancel 返回一个派生上下文和一个取消函数。当调用取消函数时,派生上下文的 Done 通道会被关闭。

ctx, cancel := context.WithCancel(context.Background())
defer cancel() // 确保资源被释放 go func() {
// 模拟一些工作
time.Sleep(2 * time.Second)
cancel() // 取消上下文
}() <-ctx.Done() // 等待上下文被取消
fmt.Println("Context canceled:", ctx.Err())

使用 context.WithTimeout

context.WithTimeout 返回一个派生上下文和一个取消函数。指定的超时时间过后,派生上下文的 Done 通道会被关闭。

ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
defer cancel() select {
case <-time.After(5 * time.Second):
fmt.Println("Operation completed")
case <-ctx.Done():
fmt.Println("Timeout:", ctx.Err())
}

使用 context.WithValue

context.WithValue 返回一个带有键值对的派生上下文,用于在请求的生命周期中传递数据。

type keyType string

func main() {
ctx := context.WithValue(context.Background(), keyType("userID"), 12345)
ProcessRequest(ctx)
} func ProcessRequest(ctx context.Context) {
userID := ctx.Value(keyType("userID")).(int)
fmt.Println("User ID:", userID)
}

典型应用场景

  1. API 请求处理: 在处理 HTTP 请求时,传递上下文以管理超时和取消。
  2. 并发任务管理: 使用上下文来控制和取消多个并发任务。
  3. 传递请求范围的数据: 例如用户身份验证信息、跟踪 ID 等。

注意事项

  • Context 是不可变的,应当通过 context.WithCancel, context.WithTimeout, context.WithDeadline, context.WithValue 等函数创建新的派生上下文。
  • 不要将 Context 存储在结构体中,应当作为函数的第一个参数传递。
  • 尽量在短生命周期的请求中使用 Context,避免长时间持有上下文。

通过正确使用 context 包,可以编写出更健壮、更易于维护的并发程序。

Go context 介绍的更多相关文章

  1. Golang的Context介绍及其源码分析

    简介 在Go服务中,对于每个请求,都会起一个协程去处理.在处理协程中,也会起很多协程去访问资源,比如数据库,比如RPC,这些协程还需要访问请求维度的一些信息比如说请求方的身份,授权信息等等.当一个请求 ...

  2. Tomcat下server.xml中context介绍

    conf/Context.xml是Tomcat公用的环境配置;若在server.xml中增加<Context path="/test" docBase="D:\te ...

  3. Go context 介绍和使用

    context 上下文管理 context 翻译过来就是上下文管理,主要作用有两个: 控制 goroutine 的超时 保存上下文数据 WithTimeout 通过下面的一个简单的 http 例子进行 ...

  4. Android Context介绍

    转载(Android Context完全解析与各种获取Context方法):https://www.cnblogs.com/chenxibobo/p/6136693.html

  5. 理解Go Context机制

    1 什么是Context 最近在公司分析gRPC源码,proto文件生成的代码,接口函数第一个参数统一是ctx context.Context接口,公司不少同事都不了解这样设计的出发点是什么,其实我也 ...

  6. Android上下文Context

    Android上下文Context介绍 在应用开发中最熟悉而陌生的朋友-----Context类 ,说它熟悉,是应为我们在开发中时刻的在与它打交道,例如:Service.BroadcastReceiv ...

  7. Golang 高效实践之并发实践context篇

    前言 在上篇Golang高效实践之并发实践channel篇中我给大家介绍了Golang并发模型,详细的介绍了channel的用法,和用select管理channel.比如说我们可以用channel来控 ...

  8. Go实现海量日志收集系统(三)

    再次整理了一下这个日志收集系统的框,如下图 这次要实现的代码的整体逻辑为: 完整代码地址为: https://github.com/pythonsite/logagent etcd介绍 高可用的分布式 ...

  9. Flask类的属性和方法大全

    Flask Property__class____dict____doc____module__app_ctx_globals_classconfig_classdebugdefault_config ...

  10. OpenGL Windows 窗口程序环境搭建

    OpenGL环境搭建步骤: Downloading OpenGL 根据官网的说法: In all three major desktop platforms (Linux, macOS, and Wi ...

随机推荐

  1. 2024UIUCTF - OSINT - Night

    2024UIUCTF - OSINT - Night 题目描述 Author: CBCicada That was quite a pretty night view, can you find wh ...

  2. NKCTF 2023 Misc

    NKCTF 2023 Misc hard-misc base32 --> N0wayBack公众号回复:NKCTF2023我来了! 得到flag:NKCTF{wtk2023Oo0oImcoM1N ...

  3. JSP快速上手与MVC模式和三层架构的知识点总结+综合案例

    阅读提示: 说明 由于JSP实在是太 难读 难写 复杂 占资源 难调试 不分离 了,拉跨!(节目效果哈,勿喷),作为一种有(ji)更(hu)好(jiu)的(yao)上(bei)位(tao)替(tai) ...

  4. 大语言模型的应用探索—AI Agent初探!

    前言 大语言模型的应用之一是与大语言模型进行聊天也就是一个ChatBot,这个应用已经很广泛了. 接下来的一个应用就是AI Agent. AI Agent是人工智能代理(Artificial Inte ...

  5. @Autowired和@Resource有哪些区别

    一.注解的作用 @Autowired和@Resource都是用来实现Bean的自动注入功能. 二.@Autowired和@Resource的区别 1.所属的包不同 @Autowired是Spring的 ...

  6. eclipse取消默认工作空间的两种方法

    对于eclipse的默认的工作空间,如果不需要正常切换workspace的用户很方便,打开eclipse便自动进入默认的工作空间.而如果用户经常在多个workspace之间切换的话,启动eclipse ...

  7. 自动化车间3D可视化设计思路

    自动化车间3D可视化设计思路 随着国内制造业企业的高速发展,再加上政策支持,高效的生产模式和先进的管理方式越来越受到企业重视.更多的企业将工业信息化技术进行广泛的应用,比如MES系统.数字孪生以及生产 ...

  8. C# ClassHelper动态创建程序集和类, 添加/删除类属性

    using System; using System.Collections.Generic; using System.Reflection; using System.Reflection.Emi ...

  9. LLM-01 大模型 本地部署运行 ChatGLM2-6B-INT4(6GB) 简单上手 环境配置 单机单卡多卡 2070Super8GBx2 打怪升级!

    搬迁说明 之前在 CSDN 上发文章,一直想着努力发一些好的文章出来!这篇文章在 2024-04-17 10:11:55 已在 CSDN 发布 写在前面 其他显卡环境也可以!但是最少要有8GB的显存, ...

  10. Python 实现Excel和TXT文本格式之间的相互转换

    Excel是一种具有强大的数据处理和图表制作功能的电子表格文件,而TXT则是一种简单通用.易于编辑的纯文本文件.将Excel转换为TXT可以帮助我们将复杂的数据表格以文本的形式保存,方便其他程序读取和 ...