Golang Context 的几种应用场景

95 篇文章 9 订阅
订阅专栏

Golang context主要用于定义超时取消,取消后续操作,在不同操作中传递值。本文通过简单易懂的示例进行说明。

超时取消

假设我们希望HTTP请求在给定时间内完成,超时自动取消。

首先定义超时上下文,设定时间返回取消函数(一旦超时用于清理资源)。调用取消函数取消后续操作,删除子上下文对父的引用。

	ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*80)
	defer cancel()
	req = req.WithContext(ctx)

还可以通过特定时间进行设定:

/ The context will be cancelled after 3 seconds
// If it needs to be cancelled earlier, the `cancel` function can
// be used, like before
ctx, cancel := context.WithTimeout(ctx, 3*time.Second)

// Setting a context deadline is similar to setting a timeout, except
// you specify a time when you want the context to cancel, rather than a duration.
// Here, the context will be cancelled on 2022-11-10 23:00:00
ctx, cancel := context.WithDeadline(ctx, time.Date(2022, time.November, 10, 23, 0, 0, 0, time.UTC))

完整实例如下:

func main() {
    //定义请求
	req, err := http.NewRequest(http.MethodGet, "https://www.baidu.com", nil)
	if err != nil {
		log.Fatal(err)
	}

    // 定义上下文
	ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*80)
	defer cancel()
	req = req.WithContext(ctx)

    // 执行请求
	c := &http.Client{}
	res, err := c.Do(req)
	if err != nil {
		log.Fatal(err)
	}
	defer res.Body.Close()

    // 输出日志
	out, err := io.ReadAll(res.Body)
	if err != nil {
		log.Fatal(err)
	}
	log.Println(string(out))
}

超时输出结果:

2022/12/27 14:36:00 Get "https://www.baidu.com": context deadline exceeded

我们可以调大超时时间,则能正常看到输出结果。

取消后续操作

有时请求被取消后,需要阻止系统继续做后续比必要的工作。请看下面用户发起的http请求,应用程序接收请求后查询数据库并返回查询结果:

正常流程如下:
在这里插入图片描述

但如果客户端取消了请求,如果没有取消,应用服务和数据库仍然继续工作,然后结果却不能反馈给客户端。理想状况为所有下游过程停止,如图所示:
在这里插入图片描述

考虑有两个相关操作的情况,“相关”的意思是如果一个失败了,另一个即使完成也没有意义了。如果已经知道前一个操作失败了,则希望取消所有相关的操作。请看示例:

func operation1(ctx context.Context) error {
	// 假设该操作因某种原因而失败
	// 下面模拟业务执行一定时间
	time.Sleep(100 * time.Millisecond)
	return errors.New("failed")
}

func operation2(ctx context.Context) {
	// 该方法要么正常执行完成
	// 要么取消,不再继续执行
	select {
	case <-time.After(500 * time.Millisecond):
		fmt.Println("done")
	case <-ctx.Done():
		fmt.Println("halted operation2")
	}
}

func main() {
	// 创建上下文
	ctx := context.Background()

	// 基于上下文创建需求上下文
	ctx, cancel := context.WithCancel(ctx)

	// 在不同协程中执行两个操作
	go func() {
		err := operation1(ctx)
		// 如果该方法返回错误,则取消该上下文中的后续操作
		if err != nil {
			cancel()
		}
	}()

	// 实用相同上下文执行操作2
	operation2(ctx)
}

由于我们设置操作2执行时间较长,而操作1很快就报错,因此输出结果为操作2被取消:

halted operation2

上下文传值

我们可以实用上下文变量在不同协程中传递值。
在这里插入图片描述

假设一个操作需要调用函数多次,其中用于标识的公共ID需要被日志记录,请看示例:

// 定义key,用于保存上下文值的键
const keyID = "id"

func main() {
    // 定义上下文值
	rand.Seed(time.Now().Unix())
	ctx := context.WithValue(context.Background(), keyID, rand.Int())
	operation1(ctx)
}

func operation1(ctx context.Context) {
	// do some work

	// we can get the value from the context by passing in the key
	log.Println("operation1 for id:", ctx.Value(keyID), " completed")
	operation2(ctx)
}

func operation2(ctx context.Context) {
	// do some work

	// this way, the same ID is passed from one function call to the next
	log.Println("operation2 for id:", ctx.Value(keyID), " completed")
}

这里在main函数中创建上下文,并采用键值对方式存储id值,从而后续函数调用时可以从上下文中获取该值。如图所示:

使用context变量在不同操作中传递信息非常有用,主要原因包括:

  1. 线程安全: 一旦设置了上下文键,就不能修改它的值,可以使用context.WithValue方法可以设置新的值

  2. 通用方法: 在Go的官方库和应用程序中大量使用上下文传递数据,我们当然最好也使用这种模式

Golang并发编程-协程goroutine任务取消(Context)
cui_win的专栏
05-25 769
在实际的业务种,我们可能会有这么一种场景:需要我们主动的通知某一个goroutine结束。比如我们开启一个后台goroutine一直做事情,比如监控,现在不需要了,就需要通知这个监控goroutine结束,不然它会一直跑,就泄漏了。我们都知道一个goroutine启动后,我们是无法控制他的,大部分情况是等待它自己结束,那么如果这个goroutine是一个不会自己结束的后台goroutine呢?比如监控等,会一直运行的。
Golang-Context扫盲与原理解析
Y先森0.0
01-14 900
Golang-Context扫盲与原理解析 一.什么是Contextcontext是一个包,是Go1.7引入的标注库,文译做上下文,准确的说是goroutine的上下文,包含goroutine的运行状态,环境,现场等信息。 context主要用于在goroutine之间传递上下文信息,比如取消信号,超时时间,截止时间,kv等。 二.为什么要有Context? 在Go,控制并发有两种经...
Go接口应用场景说明.go
09-26
GO接口应用场景说明
golangContext使用场景
轩脉刃的刀光剑影
02-19 6425
golangContext使用场景 2019-02-19 09:27 by 轩脉刃, ... 阅读, ... 评论, 收藏, 编辑 golangContext使用场景 context在Go1.7之后就进入标准库了。它主要的用处如果用一句话来说,是在于控制goroutine的生命周期。当一个计算任务被goroutine承接了...
GO协程理解和应用场景
小丑鱼的专栏
11-04 1403
最近在倒腾GO语言,用来做了一段时间研发后,发现一些特点,在此记录一下。首先学习了下他的语言语法,发现规则和其他语言规则有点类似,函数是通过大括号来进行规范,条件语句也是通过大括号在规范,然后就是else语句必须放在if的结束大括号后面,否则会报错;语法简单,不需要像C/C++语言那样需要分号来结束每条语句,直接换行即可,也不需要像python语言那样需要强要求的换行来标识语句和函数;最后就是协程,协程可以算是go语言的最大的特点,也是go语言诞生的初衷。
浅谈并发、进程通信方式、Go协程三者的简单应用场景
嵌入式Linux内核的博客
01-09 1709
一、概念 (1)并发的概念及其重要性 在早期,CPU都是以单核的形式顺序执行机器指令。Go语言的祖先C语言正是这种顺序编程语言的代表。顺序编程语言的顺序是指:所有的指令都是以串行的方式执行,在相同的时刻有且仅有一个CPU在顺序执行程序的指令。 随着处理器技术的发展,单核时代以提升处理器频率来提高运行效率的方式遇到了瓶颈,目前各种主流的CPU频率基本被锁定在了3GHZ附近。单核CPU的发展的停滞,给多核CPU的发展带来了机遇。相应地,编程语言也开始逐步向并行化的方向发展。Go语言正是在多核和网络化的时代背景
golangcontext使用
学习学习再学习
10-04 2779
背景 (欢迎关注“云原生手记”微信公众号) golang并发编程的三种实现方式:chan管道、waitGroup和Context。本篇将重点介绍context使用,告诉大家基本的使用方式,做到会用。 Context 概念介绍 context译为上下文golang在1.6.2的时候还没有自己的context,在1.7的版本就把golang.org/x/net/context包被加入到了官方的库golangContext包,是专门用来处理多个goroutine之间与请求域的数据、取消信号、截
深入Golangcontext的用法详解
09-20
Golang是一种编译型、静态类型语言,它提供了高效、简洁、可移植性强的编程模式。在Golang的并发编程模型,goroutine是一个轻量级的线程,可以轻易创建成千上万个。然而,当涉及到控制goroutine的生命周期、处理...
Golangcontext
yasinshaw的博客
01-16 1517
点击↑上方↑蓝色“编了个程”关注我~这是Yasin的第 57 篇原创文章Y说周末的快乐时光总是很短暂。今天天气不错,有点太阳。去附近的商场吃了一顿“高老九重庆火锅”,味道还行,主要是好久没...
golang context的一些思考
05-26 1119
前言 因为goroutine,go的并发非常方便,但是这也带来了另外一个问题,当我们进行一个耗时的异步操作时,如何在约定的时间内终止该操作并返回一个自定义的结果?这也是大家常说的我们如何去终止一个goroutine(因为goroutine不同于os线程,没有主动interrupt机制),这里就轮到今天的主角context登场了。 context源于google,于1.7版本加入标准库,按照官方文档的说法,它是一个请求的全局上下文,携带了截止时间、手动取消等信号,并包含一个并发安全的map用于携带数据。con
golang通过context控制并发的应用场景实现
12-23
golang 里出现多 goroutine 的场景很常见, 最常用的两种方式就是 WaitGroup 和 Context, 今天我们了解一下 Context应用场景 使用场景 场景一: 多goroutine执行超时通知 并发执行的业务最常见的就是有协程执行超时, 如果不做超时处理就会出现一个僵尸进程, 这累计的多了就会有一阵手忙脚乱了, 所以我们要在源头上就避免它们 看下面这个示例: package main import ( "context" "fmt" "time" ) /** 同一个content可以控制多个goroutine, 确保线程可控, 而不是每新建一个gor
go context应用场景
qq_39332031的博客
05-25 750
golangContext使用场景 context在Go1.7之后就进入标准库了。它主要的用处如果用一句话来说,是在于控制goroutine的生命周期。当一个计算任务被goroutine承接了之后,由于某种原因(超时,或者强制退出)我们希望止这个goroutine的计算任务,那么就用得到这个Context了。 关于Context的四种结构,CancelContext,TimeoutContext,DeadLineContext,ValueContext使用在这一篇快速掌握 Golang conte
golang context适用场景分析
学亮编程手记
06-08 313
Go 语言Context 包提供了一种机制,用于在多个 goroutine 之间传递请求范围的上下文信息,并用于控制 goroutine 的生命周期、取消操作和超时控制。Context 在并发编程有广泛的应用场景,下面是一些适用场景的分析:并发任务的取消和超时控制:当我们启动多个并发任务时,可能需要在某个条件满足或超过指定的时间后取消这些任务。使用 Context 可以创建子级 Context,并设置超时时间或通过取消函数进行任务的取消操作。
Golang协程的概念、用法、场景及案例
最新发布
hitpter的专栏
10-18 1305
协程是一种轻量级的线程,它可以实现并发执行的并行操作。协程是Go语言的一个核心特性,它使得程序能够以并发的方式运行,并且非常高效。与传统的线程相比,协程的创建和销毁成本非常低,可以方便地启动大量的协程来执行并行操作。Golang的协程不同于其他语言的线程或进程,它们是由Go语言的运行时系统调度的。协程的调度是基于协作式的,即协程自己主动让出CPU的控制权,而不是依赖于操作系统的调度器。Golang的协程是一种非常强大的并发模型,可以帮助我们编写高效的并发程序。
golangContext使用场景总结
xia_2017的博客
02-01 1098
go Context适用场景
golang Context使用场景
qq_49723651的博客
01-24 597
文章目录1.值传递2.超时控制3.取消控制 1.值传递 值传递只是context的一个辅助功能,并不是核心功能。一般我们只用context来传递不影响业务主逻辑的可选数据,比如日志信息、调试信息以及元信息等等。 package main import ( "context" "fmt" ) func readContext(ctx context.Context) { traceId, ok := ctx.Value("key").(string) if ok { fmt.Printl
Golangcontext用法
Gcaptain
06-24 8889
文章目录1. context2. context.go2.0 结构图2.1 Context interface2.2 emptyCtx2.3 cancelCtx2.4 valueCtx2.5 timerCtx3. 使用示例3.1 WithCancel3.2 WithDeadline3.3 WithTimeout3.4 WithValue 1. context Golang context 是Go语言在 golang1.7 发布时新增的标准包 目的是增强Golang开发并发控制技术 简单来讲当一个服
Go语言协程
一夜奈何梁山
09-06 393
【代码】Go语言协程。
golang context
09-13
Golang的"context"是一个用于在应用程序传递请求范围数据和控制goroutine生命周期的包。它是为了解决在不同goroutine之间传递请求相关的数据和取消或超时控制的问题而引入的。 Context包含一些方法,允许你创建和操纵context对象。你可以使用`context.Background()`创建一个根context,然后使用`context.WithCancel()`、`context.WithTimeout()`或`context.WithDeadline()`等方法创建子context来设置取消或超时控制。这些子context可以在goroutine之间传递,并且可以通过调用`context.WithValue()`方法将请求范围的数据存储在context使用context可以实现一些常见的任务,例如: - 在HTTP请求处理程序设置超时时间,以避免处理时间过长而导致的资源浪费。 - 在多个goroutine之间传递请求相关的数据,而不需要显式地传递参数。 - 取消操作,以便在长时间运行的操作优雅地终止goroutine。 总之,Golang的"context"包提供了一种简洁而灵活的方式来处理请求范围的数据传递和控制goroutine生命周期,使得开发者能够更好地处理并发和异步编程。
写文章

热门文章

  • python numpy 中linspace函数 245439
  • 使用R中merge()函数合并数据 171274
  • 介绍java中Pair 160217
  • 使用Spring @DependsOn控制bean加载顺序 118993
  • RestTemplate使用JSON发送Post请求 78177

分类专栏

  • 数据分析工程 7篇
  • 机器学习 42篇
  • ClickHouse 30篇
  • 图数据库 2篇
  • 时序数据库 1篇
  • java8~9核心功能 96篇
  • Golang 95篇
  • R语言 69篇
  • python 56篇
  • Elasticsearch 50篇
  • PostgreSQL 78篇
  • spring boot 29篇
  • spring 61篇
  • C&C++ 7篇
  • 数据库 105篇
  • kafka 10篇
  • greenplum 9篇
  • 数据结构与算法 6篇
  • spring cloud 4篇
  • linux 3篇
  • 深入理解Javascript 35篇
  • pentaho kettle 深入浅出 27篇
  • web开发 33篇
  • AMQP 2篇
  • pentaho 37篇
  • Apache Camel 1篇
  • TypeScript 2篇
  • groovy 7篇
  • spring data 9篇
  • spring security 实战 11篇
  • spring batch 12篇
  • Spring Security 8篇
  • Spring Shell 1篇
  • 大数据处理 49篇
  • MongoDB 4篇
  • redis 8篇
  • 工具软件 58篇
  • 程序感悟 8篇
  • 设计模式 17篇

最新评论

  • dbt seed 命令及应用示例

    普通网友: 学到了,细节很到位!【我也写了一些相关领域的文章,希望能够得到博主的指导,共同进步!】

  • SQL优化必知技巧——使用exists 代替 in

    Q_Z_5: 博主,假如我class_a还有附带的查询条件语法怎么写。又假如我是需要参数的形式输入list进来呢

  • 使用Jackson处理yaml文件

    香饽饽~、: 不知道为什么原来的yaml文件没有双引号,但是我写入的就有双引号,怎么能避免一下

  • PostgreSQL事件触发器实战教程

    激动的兔子: 博主的笔触细腻,文章构思精妙,字里行间流露着不凡的文采与深邃的见解。每一句都经过精心雕琢,如同晨露微光中绽放的花朵,既清新脱俗又不失深度,引人入胜。其语言流畅而富有韵律,读来如同山间清泉,潺潺入心,让人在享受文字之美的同时,也能深刻感受到作者独到的思考与情感。总之,博主的文章是一场文字的盛宴,令人回味无穷。

  • PostgreSQL NUMERIC 数据类型

    猿说新宇: 严格来说,precision是精度,scale是标度。精度即数的有效数字个数,比如,2.5的有效数字个数是2,但是053.2的有效数字个数是3

大家在看

  • 本地部署大模型的三种工具,零基础入门大模型,看这篇就够了!
  • iText 5在页眉中动态填充当前页码和总页数
  • 力扣516-最长回文子序列(Java详细题解)
  • 一招教你如何选择合适的算力
  • 17.2 ksm源码讲解

最新文章

  • dbt snapshot命令及应用示例
  • dbt seed 命令及应用示例
  • # dbt source & dbt source freshness命令详解
2024年10篇
2023年68篇
2022年132篇
2021年135篇
2020年124篇
2019年126篇
2018年98篇
2017年60篇
2016年63篇
2015年32篇
2014年44篇
2013年3篇
2012年4篇
2010年2篇
2009年4篇

目录

目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值

玻璃钢生产厂家大理市玻璃钢雕塑公司赤峰玻璃钢雕塑定制价格湖里园林玻璃钢雕塑批发佛山玻璃钢雕塑手工制作玻璃钢仿真植物水果雕塑制造商万源玻璃钢雕塑厦门做玻璃钢雕塑公园校园玻璃钢雕塑制造北京专业玻璃钢雕塑玻璃钢雕塑哪家比较不错秋季商场美陈制造定西城市玻璃钢雕塑价格灵宝商场美陈淮安玻璃钢雕塑公司奉节县玻璃钢雕塑南阳玻璃钢雕塑厂家电话平凉玻璃钢卡通雕塑公司吉安环保玻璃钢雕塑生产厂家玻璃钢不锈钢树叶雕塑定制百色玻璃钢雕塑公司番禺区玻璃钢雕塑厂金昌玻璃钢动物雕塑安装玻璃钢雕塑卡通哪家质量好玻璃钢手提包雕塑商场顶上美陈挂饰广场玻璃钢雕塑哪家好卡通玻璃钢雕塑的分类广场玻璃钢玩偶雕塑定制长沙玻璃钢雕塑制造商树脂玻璃钢雕塑生产商香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化