Go context 介绍
在 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:
context.Background()context.TODO()context.WithCancel(parent Context)context.WithTimeout(parent Context, timeout time.Duration)context.WithDeadline(parent Context, deadline time.Time)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)
}
典型应用场景
- API 请求处理: 在处理 HTTP 请求时,传递上下文以管理超时和取消。
- 并发任务管理: 使用上下文来控制和取消多个并发任务。
- 传递请求范围的数据: 例如用户身份验证信息、跟踪 ID 等。
注意事项
Context是不可变的,应当通过context.WithCancel,context.WithTimeout,context.WithDeadline,context.WithValue等函数创建新的派生上下文。- 不要将
Context存储在结构体中,应当作为函数的第一个参数传递。 - 尽量在短生命周期的请求中使用
Context,避免长时间持有上下文。
通过正确使用 context 包,可以编写出更健壮、更易于维护的并发程序。
Go context 介绍的更多相关文章
- Golang的Context介绍及其源码分析
简介 在Go服务中,对于每个请求,都会起一个协程去处理.在处理协程中,也会起很多协程去访问资源,比如数据库,比如RPC,这些协程还需要访问请求维度的一些信息比如说请求方的身份,授权信息等等.当一个请求 ...
- Tomcat下server.xml中context介绍
conf/Context.xml是Tomcat公用的环境配置;若在server.xml中增加<Context path="/test" docBase="D:\te ...
- Go context 介绍和使用
context 上下文管理 context 翻译过来就是上下文管理,主要作用有两个: 控制 goroutine 的超时 保存上下文数据 WithTimeout 通过下面的一个简单的 http 例子进行 ...
- Android Context介绍
转载(Android Context完全解析与各种获取Context方法):https://www.cnblogs.com/chenxibobo/p/6136693.html
- 理解Go Context机制
1 什么是Context 最近在公司分析gRPC源码,proto文件生成的代码,接口函数第一个参数统一是ctx context.Context接口,公司不少同事都不了解这样设计的出发点是什么,其实我也 ...
- Android上下文Context
Android上下文Context介绍 在应用开发中最熟悉而陌生的朋友-----Context类 ,说它熟悉,是应为我们在开发中时刻的在与它打交道,例如:Service.BroadcastReceiv ...
- Golang 高效实践之并发实践context篇
前言 在上篇Golang高效实践之并发实践channel篇中我给大家介绍了Golang并发模型,详细的介绍了channel的用法,和用select管理channel.比如说我们可以用channel来控 ...
- Go实现海量日志收集系统(三)
再次整理了一下这个日志收集系统的框,如下图 这次要实现的代码的整体逻辑为: 完整代码地址为: https://github.com/pythonsite/logagent etcd介绍 高可用的分布式 ...
- Flask类的属性和方法大全
Flask Property__class____dict____doc____module__app_ctx_globals_classconfig_classdebugdefault_config ...
- OpenGL Windows 窗口程序环境搭建
OpenGL环境搭建步骤: Downloading OpenGL 根据官网的说法: In all three major desktop platforms (Linux, macOS, and Wi ...
随机推荐
- 构建高可用性、高性能和可扩展的Zabbix Server架构
简介 本教程讲解了一下如何设计构建一个高性能.高可靠.高扩展的Zabbix 监控集群. 架构图 架构图PDF下载: https://songxwn.com/file/Zabbix_HA.pdf Pig ...
- P9120 题解
暴力容斥复活之路! \(k=1\) 这个你肯定会. \(k=2\) 大的放上去,小的放下来.简单贪心. \(k=3\) 考虑二分答案. 然后考虑判断是否合法. 令当前答案为 \(val\). 首先钦定 ...
- Linux 提权-SUID/SGID_2
本文通过 Google 翻译 SUID | SGID Part-2 – Linux Privilege Escalation 这篇文章所产生,本人仅是对机器翻译中部分表达别扭的字词进行了校正及个别注释 ...
- Django详细笔记
django 学习 特点 快速开发 安全性高 可伸缩性强 URL 组成部分 URL: 同意资源定位符 一个URL由以下几部分组成 scheme://host:port/path/?query-stri ...
- 使用Eclipse开发Vue——CodeMix够智能
使用Eclipse开发Vue--CodeMix够智能 Eclipse的CodeMix插件允许您访问 VS Code和Code OSS扩展社区,以及 Webclipse 1.x 功能. Vue.js是构 ...
- [Unity] Dreamteck Splines实现沿路径移动功能
Dreamteck Splines实现沿路径移动功能 最近有一个"让物体沿固定路径移动"的需求,因此接触到了Dreamteck Splines插件. Dreamteck Splin ...
- 10 pdf分享失败
PC端分享pdf,复制粘贴pdf链接后跳转搜索首页
- leetcode简单(数组,字符串,链表):[66, 67, 70, 83, 121, 141, 160, 169, ,206, 338]
目录 66. 加一 67. 二进制求和 70. 爬楼梯 83. 删除排序链表中的重复元素 121. 买卖股票的最佳时机 141. 环形链表 160. 相交链表 169. 多数元素 206. 反转链表 ...
- Linux 文本文件编辑相关命令简介【Linux 常用命令系列二】
〇.前言 本文介绍了如何通过 vim 命令,对文本文件进行打开.编辑.保存等相关操作,并通过简单的示例演示了常用用法. 一.关于文本文件的操作 1.1 打开,查看(cat).编辑(vim) 打开文本文 ...
- java面试一日一题:讲下ThreadLocal
问题:请讲下ThreadLocal 分析:首先要了解ThreadLocal的基本原理:其次要理解ThreadLocal发生内存泄漏的原因:最后ThreadLocal是如何做到线程隔离的 回答要点: 主 ...