在 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. k8s网络原理之flannel

    首先当你创建一个k8s集群后一般会存在三种IP分别是,Pod IP,Node IP,Cluster IP 其中一个Cluster IP之下包含多个Node IP,而一个Node IP之下又包含多个Po ...

  2. aiohttp 子线程启动/中止服务

    import time, threading from aiohttp import web import asyncio async def handler(request): return web ...

  3. CF372C

    思路 根据题意可以得到dp转移方程是 \(f_{i,j}=\max\{f_{i-1,k}+b_i-|a_i-j|\}\) 而且 \(j-(t_{i}-t_{i-1})\times d\le k\le ...

  4. Java-Spring JDBC初体验操作数据库

    Spring JDBC * Spring框架对JDBC的简单封装 提供了一个JDBCTemplate对象简化JDBC的开发 步骤 导入jar包 创建JDBCTemplate对象,依赖于数据源DataS ...

  5. Java实现快速快速排序算法

    算法简介 快速排序(Quick Sort) 是由冒泡排序改进而得的.在冒泡排序过程中,只对相邻的两个记录进行比较,因此每次交换两个相邻记录时只能消除一个逆序.如果能通过两个(不相邻)记录的一次交换直接 ...

  6. [oeasy]python0094_视频游戏_双人网球_pong_atari_mos_6502_雅达利_米洛华

    编码进化 回忆上次内容 上次 我们回顾了 微软之前的 比尔盖茨和保罗艾伦 mits 迎来的 是帮手 还是隐患? intel-8080 遇到了 mos-6502 底层硬件 驱动 游戏行业进化 不光是扑克 ...

  7. 题解:AT_xmascon21_b Bad Mood

    AT_xmascon21_b Bad Mood 题意 给定你一个 \(n\times m\) 的矩形. 以一条对角线为基础上,制作一个无向图,该图的顶点对应于格子的共有 \((m+1) \times ...

  8. OpenGL 三角形颜色插值

    1.最懒的方法--Nearest Neighbor对于三角形内的点,离三个顶点谁最近,就赋值为那个顶点对应的颜色. 2.最天真的方法--Distance三角形内一点的值应该来自于三个顶点. 计算距离: ...

  9. linux性能资源分析工具

    linux性能资源分析工具 1,top 2,ps 3,uptime 4,mpstat 5,pidstat 6,vmstat 7,iostat 8,netstat 9,lsof 10,sar / nmo ...

  10. linux中grep的用法详解

    linux中grep的用法详解 grep (global search regular expression(RE) and print out the line,全面搜索正则表达式并把行打印出来)是 ...