当前位置: 首页 > news >正文

golang中的上下文

背景

在Go语言中,使用context包来管理跨API和进程间的请求生命周期是常见的做法。特别是在涉及到并发编程时,如启动协程(goroutine)来处理异步任务,正确地传递和监听context变得尤为重要。比如,在gin框架中,发起一个http请求,把context传递到协程中,当http请求结束时就会执行上下文取消逻辑,从而导致异步协程退出。

我们通过一个示例模拟在gin框架(或任何类似的Web框架)中可能遇到的一个问题:在HTTP请求处理过程中启动协程,并传递context以控制协程的生命周期。

package mainimport ("context""fmt""time"
)func main() {// 创建一个带取消功能的上下文ctx, cancel := context.WithCancel(context.Background())// 启动一个协程go func(ctx context.Context) {ticker := time.NewTicker(1 * time.Second)defer ticker.Stop() // 确保ticker在退出时停止for {select {case <-ticker.C:fmt.Println("协程正在运行...")case <-ctx.Done():fmt.Println("协程收到取消信号,退出执行")return}}}(ctx)// 主程序等待3秒后取消上下文time.Sleep(3 * time.Second)cancel()time.Sleep(1 * time.Second)fmt.Println("主程序结束")
}

当我们执行取消操作,异步协程监听到Done信号,执行了退出协程的逻辑。 

但是,在某些情况下,比如,上述提到的http请求这样的情况下,我们并不期望context取消,导致异步协程退出执行。

那我们应该怎么办呢?

很容易想到的是new一个新的context使其继承父context。但是,这里就会遇到一个问题,简单的拷贝父context是不行的,比如,下面这种写法,当父ctx取消了,newCtx也会取消。

ctx, cancel := context.WithCancel(context.Background())newCtx, _ := context.WithTimeout(ctx, 3*time.Second)

那么要怎么办呢?context包中有一个方法:WithoutCancel,这个方法只拷贝了父ctx的Value,没有继承父ctx的Done通道。

案例

我们提供一个简单的案例,模拟在协程中处理逻辑。

package mainimport ("context""fmt""time"
)func main() {// 创建一个带取消功能的上下文ctx, cancel := context.WithCancel(context.Background())ctx = context.WithValue(ctx, "traceId", "123456")ctx = context.WithValue(ctx, "userId", "u123")newCtx := context.WithoutCancel(ctx)// 启动一个协程go func(ctx context.Context) {ticker := time.NewTicker(1 * time.Second)defer ticker.Stop() // 确保ticker在退出时停止for {select {case <-ticker.C:fmt.Println("traceId:", ctx.Value("traceId"))fmt.Println("userId:", ctx.Value("userId"))fmt.Println("协程正在运行...")case <-ctx.Done():fmt.Println("协程收到取消信号,退出执行")return}}}(newCtx)// 主程序等待3秒后取消上下文time.Sleep(3 * time.Second)cancel()<-newCtx.Done()// 这种情况下,不会收到取消信号,父上下文的取消信号不会传递给子上下文// 给协程一些时间进行清理和输出time.Sleep(1 * time.Second)fmt.Println("主程序结束")
}

在Go语言的context包中,WithoutCancel函数提供了一种创建新上下文的方法,这个新上下文不会继承其父上下文的取消逻辑。这意味着,当父上下文被取消时,由WithoutCancel返回的上下文并不会被自动取消。

// WithoutCancel 返回一个父上下文的副本,该副本在父上下文被取消时不会被取消。  
// 返回的上下文没有截止时间或错误,并且其 Done 通道为 nil。  
// 对返回的上下文调用 [Cause] 方法会返回 nil。  
func WithoutCancel(parent Context) Context {if parent == nil {panic("cannot create context from nil parent")}return withoutCancelCtx{parent}
}type withoutCancelCtx struct {c Context
}// withoutCancelCtx 类型的 Done 方法被重写,返回 nil 通道。  
func (w withoutCancelCtx) Done() <-chan struct{} {  return nil // 返回空的 Done 通道,表示这个上下文不会被取消  
}

WithoutCancel函数接受一个父上下文作为参数,并返回一个新的上下文。这个新上下文是一个withoutCancelCtx类型的实例,它内部包含了父上下文,但重写了Done方法。

由于withoutCancelCtx重写了Done方法并返回nil,这意味着当你监听这个上下文的Done通道时,它永远不会关闭,因此你的协程或任务将不会因为父上下文的取消而退出。这对于需要确保某些任务在父上下文取消后仍然继续运行的场景非常有用。

相关文章:

golang中的上下文

背景 在Go语言中&#xff0c;使用context包来管理跨API和进程间的请求生命周期是常见的做法。特别是在涉及到并发编程时&#xff0c;如启动协程&#xff08;goroutine&#xff09;来处理异步任务&#xff0c;正确地传递和监听context变得尤为重要。比如&#xff0c;在gin框架中…...

Navigation2 算法流程

转自 https://zhuanlan.zhihu.com/p/405670882 此文仅作学习笔记 启动流程 在仿真环境中启动导航包的示例程序&#xff0c;执行nav2_bringup/bringup/launch/tb3_simulation_launch.py文件。ROS2的launch文件支持采用python语言来编写以支持更加复杂的功能&#xff0c;本文件…...

OpenAI swarm+ Ollama快速构建本地多智能体服务 - 1. 服务构建教程

OpenAI开源了多智能体编排的工程swarm&#xff0c;今天介绍一下swarm与OLLAMA如何结合使用的教程&#xff0c;在本地构建自己的多智能体服务&#xff0c;并给大家实践演示几个案例。 安装步骤 安装ollama&#xff0c;在官网下载对应操作系统的版本即可&#xff0c;下载后用ol…...

HTB:Wifinetic[WriteUP]

目录 连接至HTB并启动靶机 1.What is the name of the OpenWRT backup file accessible over FTP? 使用nmap对靶机21、22端口进行脚本、服务信息扫描 2.Whats the WiFi password for SSID OpenWRT? 3.Which user reused the WiFi password on thier local account? 4.…...

专业学习|马尔可夫链(概念、变体以及例题)

一、马尔可夫链的概念及组成 &#xff08;一&#xff09;学习资料分享 来源&#xff1a;024-一张图&#xff0c;但讲懂马尔可夫决策过程_哔哩哔哩_bilibili 马尔可夫链提供了一种建模随机过程的方法&#xff0c;具有广泛的应用。在实际问题中&#xff0c;通过转移概率矩阵及初…...

RK3576 安卓SDK编译环境搭建

编译 Android14 对机器的配置要求较高: 建议预留500G存储 多分配CPU和内存 建议使用 Ubuntu 20.04 操作系统或更高版本 sudo apt-get updatesudo apt-get install make gcc sudo apt-get install g++ patchelf gawk texinfo chrpath diffstat binfmt-support sudo apt-get …...

Renesas R7FA8D1BH (Cortex®-M85) 上光电编码器测速功能

目录 概述 1 软硬件 1.1 软硬件环境信息 1.2 开发板信息 1.3 调试器信息 2 硬件架构 2.1 硬件框架结构 2.2 测速功能原理介绍 2.2.1 理论描述 2.2.2 实现原理 2.2.3 系统硬件结构 3 软件实现 3.1 FSP配置项目 3.2 代码实现 3.2.1 初始化函数 3.2.2 功能函数 3.…...

软件测试学习笔记丨Linux三剑客-sed

本文转自测试人社区&#xff0c;原文链接&#xff1a;https://ceshiren.com/t/topic/32521 一、简介 sed&#xff08;Stream editor&#xff09;是一个功能强大的文本流编辑器&#xff0c;主要用于对文本进行处理和转换。它适用于自动化处理大量的文本数据&#xff0c;能够支持…...

Vue脚手架学习 vue脚手架配置代理、插槽、Vuex使用、路由、ElementUi插件库的使用

目录 1.vue脚手架配置代理 1.1 方法一 1.2 方法二 2.插槽 2.1 默认插槽 2.2 具名插槽 2.3 作用域插槽 3.Vuex 3.1 概念 3.2 何时使用&#xff1f; 3.3 搭建vuex环境 3.4 基本使用 3.5 getters的使用 3.6 四个map方法的使用 3.6.1 mapState方法 3.6.2 mapGetter…...

使用yml文件安装环境时,如何添加conda和pip的镜像源

博客参考 添加conda镜像源 name: NAME channels:- conda-forge- pytorch- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/r- https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/msys2- defaults depende…...

c语言经典100例

1.字符串转为数字 #include <stdio.h>int strToInt(char *s) {int num0;int sign1;int step1;if (*s -){sign -1;s;}while (*s > 0&&*s < 9){num num*10(*s-0);step 10;s;}return num*sign; }int main() {char a[10] "-1234";char *s a ;pr…...

百易云资产管理运营系统 ufile.api.php SQL注入漏洞复现

0x01 产品描述&#xff1a; 百易云资产管理运营系统&#xff0c;是专门针对企业不动产资产管理和运营需求而设计的一套综合解决方案。该系统能够覆盖资产的全生命周期管理&#xff0c;包括资产的登记、盘点、评估、处置等多个环节&#xff0c;同时提供强大的运营分析功能&#…...

【分布式微服务云原生】《Redis RedLock 算法全解析:应对时钟漂移与网络分区挑战》

《Redis RedLock 算法全解析&#xff1a;应对时钟漂移与网络分区挑战》 摘要&#xff1a; 本文深入探讨 Redis 的 RedLock 算法&#xff0c;详细阐述其步骤及工作原理&#xff0c;同时重点分析该算法如何处理时钟漂移和网络分区这两个常见的分布式系统问题。读者将通过本文深入…...

OceanBase 的写盘与传统数据库有什么不同?

背景 在数据库开发过程中&#xff0c;“写盘”是一项核心操作&#xff0c;即将内存中暂存的数据安全地转储到磁盘上。在诸如MySQL这样的传统数据库管理系统中&#xff0c;写盘主要有以下几步&#xff1a;首先将数据写入缓存池&#xff1b;其次&#xff0c;为了确保数据的完整性…...

用Java爬虫API,轻松获取taobao商品SKU信息

在电子商务的世界里&#xff0c;SKU&#xff08;Stock Keeping Unit&#xff0c;库存单位&#xff09;是商品管理的基础。对于商家来说&#xff0c;SKU的详细信息对于库存管理、价格策略制定、市场分析等都有着重要作用。taobao作为中国最大的电子商务平台之一&#xff0c;提供…...

OpenHarmony 入门——ArkUI 自定义组件内同步的装饰器@State小结(二)

文章大纲 引言一、组件内状态装饰器State1、初始化2、使用规则3、变量的传递/访问规则说明4、支持的观察变化的场景5、State 变量的值初始化和更新机制6、State支持联合类型实例 引言 前一篇文章OpenHarmony 入门——ArkUI 自定义组件之间的状态装饰器小结&#xff08;一&…...

【Linux驱动开发】嵌入式Linux驱动开发基本步骤,字符设备开发入门,点亮LED

【Linux驱动开发】嵌入式Linux驱动开发基本步骤&#xff0c;字符设备开发入门&#xff0c;点亮LED 文章目录 开发环境驱动文件编译驱动安装驱动自动创建设备节点文件 驱动开发驱动设备号地址映射&#xff0c;虚拟内存和硬件内存地址字符驱动旧字符驱动新字符驱动 应用程序开发…...

搬砖14、Python网络编程入门

网络编程入门 计算机网络基础 计算机网络是独立自主的计算机互联而成的系统的总称&#xff0c;组建计算机网络最主要的目的是实现多台计算机之间的通信和资源共享。今天计算机网络中的设备和计算机网络的用户已经多得不可计数&#xff0c;而计算机网络也可以称得上是一个“复…...

Transformer: Attention is All you need

Transformer Transformer是基于Encoder-Decoder结构的&#xff0c;将Seq2Seq中的RNN/GRU部分更换为Self-Attention部分 位置编码 Positional Encoding Self-attention丢失了位置信息 CNN 卷积神经网络可以保存相邻的位置信息 RNN 是顺序输入的&#xff0c;是包含了位置信息…...

C++:排序算法

目录 一、插入排序 1.直接插入排序 2.希尔排序 二、交换排序 1.冒泡排序 2.快速排序 三、选择排序 1.简单选择排序 2.堆排序 四、归并排序 1.二路归并排序的递归实现 2.二路归并排序的非递归实现 一、插入排序 1.直接插入排序 直接插入排序的基本思想是&#xff…...

wordpress后台更新后 前端没变化的解决方法

使用siteground主机的wordpress网站&#xff0c;会出现更新了网站内容和修改了php模板文件、js文件、css文件、图片文件后&#xff0c;网站没有变化的情况。 不熟悉siteground主机的新手&#xff0c;遇到这个问题&#xff0c;就很抓狂&#xff0c;明明是哪都没操作错误&#x…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

【人工智能】神经网络的优化器optimizer(二):Adagrad自适应学习率优化器

一.自适应梯度算法Adagrad概述 Adagrad&#xff08;Adaptive Gradient Algorithm&#xff09;是一种自适应学习率的优化算法&#xff0c;由Duchi等人在2011年提出。其核心思想是针对不同参数自动调整学习率&#xff0c;适合处理稀疏数据和不同参数梯度差异较大的场景。Adagrad通…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地

借阿里云中企出海大会的东风&#xff0c;以**「云启出海&#xff0c;智联未来&#xff5c;打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办&#xff0c;现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

C++ 基础特性深度解析

目录 引言 一、命名空间&#xff08;namespace&#xff09; C 中的命名空间​ 与 C 语言的对比​ 二、缺省参数​ C 中的缺省参数​ 与 C 语言的对比​ 三、引用&#xff08;reference&#xff09;​ C 中的引用​ 与 C 语言的对比​ 四、inline&#xff08;内联函数…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

今日科技热点速览

&#x1f525; 今日科技热点速览 &#x1f3ae; 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售&#xff0c;主打更强图形性能与沉浸式体验&#xff0c;支持多模态交互&#xff0c;受到全球玩家热捧 。 &#x1f916; 人工智能持续突破 DeepSeek-R1&…...