go 上下文:context.Context
Go语言中的上下文(Context)是一种用于在 Goroutines 之间传递取消信号、截止时间和其他请求范围值的标准方式。context 包提供了 Context 类型和一些相关的函数,用于在并发程序中有效地传递上下文信息。
在Go语言中,上下文通常用于以下场景:
- 请求的传递:当一个请求从客户端发送到服务器时,可以使用上下文来携带与该请求相关的数据。这些数据可以是用户的身份信息、请求的元数据或其他与请求相关的信息。通过将上下文传递给处理该请求的goroutine,可以确保在整个处理过程中访问这些数据。
- 取消操作:上下文可以用于取消正在进行的操作。当用户或其他代码发送取消信号时,可以将该信号传递给正在执行操作的goroutine。goroutine在接收到取消信号后,可以根据需要执行清理操作并退出。
- 截止时间:有时候需要在一段时间后终止正在进行的操作。通过将截止时间与上下文一起传递给goroutine,可以确保在超过截止时间后执行适当的清理操作并退出。
- 跨多个服务通信:当在分布式系统中使用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.WithCancel、context.WithTimeout、context.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 也会相应地被取消。
声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意
go 上下文:context.Context的更多相关文章
- ZeroMQ接口函数之 :zmq_term - 终结ZMQ环境上下文(context)
ZeroMQ 官方地址 :http://api.zeromq.org/4-0:zmq_term zmq_term(3) ØMQ Manual - ØMQ/4.1.0 Name zmq_term - 终 ...
- Tomcat部署web项目,虚拟目录,上下文(Context),WEB-INF,web.xml,servlet,404
Web项目的uri模型大致如下: http://localhost:8080 (/context) (/resource) 站点/上下文/资源 一. Tomcat中指定上下文(Context) 方法一 ...
- javascript作用域(Scope),简述上下文(context)和作用域的定义
网页制作Webjx文章简介:这篇文章将正面解决这个问题:简述上下文(context)和作用域的定义,分析可以让我们掌控上下文的两种方法,最后深入一种高效的方案,它能有效解决我所碰到的90%的问题. 作 ...
- Android开发之Android Context,上下文(Activity Context, Application Context)
转载:http://blog.csdn.net/lmj623565791/article/details/40481055 1.Context概念Context,相信不管是第一天开发Android,还 ...
- 层叠上下文 Stacking Context
层叠上下文 Stacking Context 在CSS2.1规范中,每个盒模型的位置是三维的,分别是平面画布上的x轴,y轴以及表示层叠的z轴.对于每个html元素,都可以通过设置z-index属性来设 ...
- (转)Docker镜像构建上下文(Context)
镜像构建上下文(Context) Docker在构建镜像时,如果注意,会看到 docker build 命令最后有一个 ... 表示当前目录,而 Dockerfile 就在当前目录,因此不少初学者以为 ...
- Docker镜像构建上下文(Context)
镜像构建上下文(Context) Dicker在构建镜像时,如果注意,会看到 docker build 命令最后有一个 ... 表示当前目录,而 Dockerfile 就在当前目录,因此不少初学者以为 ...
- Flask 上下文(Context)原理解析
:first-child { margin-top: 0; } blockquote > :last-child { margin-bottom: 0; } img { border: 0; m ...
- 上下文(Context)和作用域(Scope)
函数的每次调用都有与之紧密相关的作用域和上下文.从根本上来说,作用域是基于函数的,而上下文是基于对象的. 换句话说,作用域涉及到所被调用函数中的变量访问,并且不同的调用场景是不一样的.上下文始终是th ...
- OpenJDK源码研究笔记(十三):Javac编译过程中的上下文容器(Context)、单例(Singleton)和延迟创建(LazyCreation)3种模式
在阅读Javac源码的过程中,发现一个上下文对象Context. 这个对象用来确保一次编译过程中的用到的类都只有一个实例,即实现我们经常提到的"单例模式". 今天,特意对这个上下文 ...
随机推荐
- 查看Nginx是否启动
查看Nginx进程 ps -ef | grep nginx 输出如下: root 1036 1 0 Jul15 ? 00:00:00 nginx: master process /www/server ...
- 王道oj/problem13(用递归数楼梯)
网址:http://oj.lgwenda.com/problem/13 思路:用递归写step(int n):return step(n-1)+step(n-2); 停止条件是:n=1为1:n=2为2 ...
- 三 APPIUM Android自动化 测试初体验(转)
1.创建一个maven项目 成功新建工程: 编辑pom.xml,在<dependencies></dependencies>下添加appium相关依赖: <depende ...
- javescript入门
js组成和基本结构 javascript缘由:可以实现html,css初级验证实现不了的复杂的验证 减轻服务器压力(在发送请求到服务器之前用javescript验证客户端) w3c标准:结构化(htm ...
- 【Unity3D】激光雷达特效
1 由深度纹理重构世界坐标 屏幕深度和法线纹理简介中对深度和法线纹理的来源.使用及推导过程进行了讲解,本文将介绍使用深度纹理重构世界坐标的方法,并使用重构后的世界坐标模拟激光雷达特效. 本文完 ...
- vue 实现 pdf 预览功能
1 技术背景 1.1 Vue.js 简介和特点 Vue.js 是一种用于构建用户界面的渐进式框架.它具有以下特点: 易学易用:Vue.js 的 API 设计简单直观,使得开发者可以快速上手. 响应式数 ...
- Linux 内核 ASoC DMA 引擎驱动程序
Linux 内核 ASoC 框架,在概念上将嵌入式音频系统拆分为多个可复用的组件驱动程序,包括 Codec 类驱动程序.平台类驱动程序和机器类驱动程序.在实现上,机器类驱动程序用 struct snd ...
- 《CTFshow-Web入门》06. Web 51~60
@ 目录 web51 题解 web52 题解 原理 web53 题解 原理 web54 题解 原理 web55 题解 原理 web56 题解 原理 web57 题解 原理 web58 题解 原理 we ...
- BeanUtils.copyProperties:曾经是我的女神,现在是我的毒药。
前言 BeanUtils.copyProperties十有八九是你这些年工作中用的很多的其中一个,不管是Apache的还是Spring的. 网上的解释浩如烟海,我这边用一个超简单的例子直观展示给你看. ...
- Antd Form表单中Input输入框 在IE9下按下任何按键都会报校验失败
antd Form表单中Input输入框 在IE9下按下任何按键都会报校验失败,导致输入框输入不了任何内容! 可能你的react及react-dom版本由于过高导致antd组件不能兼容,需要对reac ...