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

Golang 并发编程:Context 包的使用与并发控制

文章目录

      • 一、简介
      • 二、Context 的基本概念
        • 1. `context` 包常用函数
      • 三、Context 的基本用法
        • 1. `WithCancel`:取消任务的上下文
      • 四、超时控制:`WithTimeout` 和 `WithDeadline`
        • 1. 使用 `WithTimeout` 控制任务超时
        • 2. 使用 `WithDeadline` 设定截止时间
      • 五、传递上下文中的数据:`WithValue`
      • 六、Context 的应用场景
      • 七、完整示例:多任务协作控制
      • 八、小结

一、简介

在并发编程中,任务管理和资源控制是非常重要的,而 Golang 的 context 为我们提供了一种优雅的方式来传递取消信号超时控制Context 用于在多个 Goroutine 之间传递上下文信息,避免 Goroutine 无法按需停止而导致资源浪费。

本篇博客将详细介绍 context 包的用法,并通过实例讲解如何在超时、取消任务多 Goroutine 协作场景中使用它。


二、Context 的基本概念

Context 是一种携带取消信号、截止时间(超时)和元数据的上下文对象,主要用于父 Goroutine 与子 Goroutine 的协作。它通过层级化的结构来管理多个并发任务。

1. 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, value interface{}):传递携带额外数据的上下文。

三、Context 的基本用法

1. WithCancel:取消任务的上下文

示例:使用 WithCancel 取消 Goroutine

package mainimport ("context""fmt""time"
)func worker(ctx context.Context, id int) {for {select {case <-ctx.Done(): // 接收取消信号fmt.Printf("Worker %d stopped\n", id)returndefault:fmt.Printf("Worker %d is working...\n", id)time.Sleep(time.Second)}}
}func main() {ctx, cancel := context.WithCancel(context.Background()) // 创建可取消的上下文for i := 1; i <= 3; i++ {go worker(ctx, i)}time.Sleep(3 * time.Second) // 模拟主 Goroutine 的其他工作fmt.Println("Cancelling all workers...")cancel() // 发送取消信号time.Sleep(1 * time.Second) // 等待所有 Goroutine 退出fmt.Println("All workers stopped.")
}

输出:

Worker 1 is working...
Worker 2 is working...
Worker 3 is working...
...
Cancelling all workers...
Worker 1 stopped
Worker 2 stopped
Worker 3 stopped
All workers stopped.

解析:

  • context.WithCancel 创建的上下文可以通过调用 cancel() 发送取消信号,从而优雅地停止所有子 Goroutine。

四、超时控制:WithTimeoutWithDeadline

1. 使用 WithTimeout 控制任务超时

示例:在 2 秒内完成任务,否则超时退出

package mainimport ("context""fmt""time"
)func worker(ctx context.Context) {select {case <-time.After(3 * time.Second): // 模拟长时间任务fmt.Println("Task completed")case <-ctx.Done(): // 接收超时信号fmt.Println("Task timed out")}
}func main() {ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) // 设置 2 秒超时defer cancel() // 确保资源释放go worker(ctx)time.Sleep(4 * time.Second) // 等待任务完成或超时
}

输出:

Task timed out

解析:

  • 通过 context.WithTimeout 创建的上下文,2 秒内未完成任务时自动发送取消信号。
  • 超时上下文可避免 Goroutine 无限期运行,帮助更好地管理资源。
2. 使用 WithDeadline 设定截止时间

WithDeadlineWithTimeout 类似,只是使用具体的时间点来控制超时。


五、传递上下文中的数据:WithValue

有时,我们需要在多个 Goroutine 之间传递一些元数据。WithValue 允许我们将键值对存入上下文,并在子 Goroutine 中访问。

示例:传递用户信息

package mainimport ("context""fmt""time"
)func greetUser(ctx context.Context) {if user, ok := ctx.Value("user").(string); ok {fmt.Printf("Hello, %s!\n", user)} else {fmt.Println("No user found.")}
}func main() {ctx := context.WithValue(context.Background(), "user", "Alice") // 在上下文中存入用户信息go greetUser(ctx)time.Sleep(1 * time.Second) // 确保 Goroutine 执行完毕
}

输出:

Hello, Alice!

解析:

  • WithValue 允许我们为上下文设置键值对,便于在多 Goroutine 间传递数据。

注意:

  • 不建议用 WithValue 传递重要的控制信息,例如取消信号或超时。

六、Context 的应用场景

  1. API 请求的超时控制:确保 HTTP 请求不会无限期等待。
  2. 任务取消:当用户主动取消某个操作时,通知相关的 Goroutine 停止工作。
  3. 传递元数据:例如在服务链路中传递用户身份、请求 ID 等信息。

七、完整示例:多任务协作控制

示例:启动多个任务,随时可取消所有任务

package mainimport ("context""fmt""sync""time"
)func worker(ctx context.Context, id int, wg *sync.WaitGroup) {defer wg.Done()for {select {case <-ctx.Done():fmt.Printf("Worker %d stopped\n", id)returndefault:fmt.Printf("Worker %d is processing...\n", id)time.Sleep(500 * time.Millisecond)}}
}func main() {var wg sync.WaitGroupctx, cancel := context.WithCancel(context.Background()) // 创建上下文for i := 1; i <= 3; i++ {wg.Add(1)go worker(ctx, i, &wg)}time.Sleep(2 * time.Second)fmt.Println("Cancelling all workers...")cancel() // 取消所有任务wg.Wait() // 等待所有任务完成fmt.Println("All workers stopped.")
}

输出:

Worker 1 is processing...
Worker 2 is processing...
Worker 3 is processing...
...
Cancelling all workers...
Worker 1 stopped
Worker 2 stopped
Worker 3 stopped
All workers stopped.

八、小结

  1. Context 用于并发控制:在 Goroutine 中传递取消信号、超时信号或携带元数据。
  2. 超时控制与资源管理:使用 WithTimeoutWithCancel 及时终止任务,避免资源浪费。
  3. 多 Goroutine 协作:通过 Context 实现多个 Goroutine 之间的优雅通信。

相关文章:

Golang 并发编程:Context 包的使用与并发控制

文章目录 一、简介二、Context 的基本概念1. context 包常用函数 三、Context 的基本用法1. WithCancel&#xff1a;取消任务的上下文 四、超时控制&#xff1a;WithTimeout 和 WithDeadline1. 使用 WithTimeout 控制任务超时2. 使用 WithDeadline 设定截止时间 五、传递上下文…...

QGraphics类型学习使用【Qt】【C++】

QGraphics类型学习使用 需求过程全部完整代码 首先已知&#xff0c;QGraphicsView&#xff0c;QGraphicsScene, QGraphicsItem&#xff0c;分别称为&#xff1a;视图&#xff0c;场景&#xff0c;图元&#xff0c;图表就是各种各样的元素&#xff0c;图片元素&#xff0c;线条元…...

迁移学习和在线学习小结

迁移学习 英文小名: transform learning 简介: 把已经训练好的模型A为基本, 在新场景中, 根据新数据建立模型B 目的: 将某个领域或任务上学习到的知识/模式, 应用到不同但相关的领域/问题中 方法: 1.结构引用 适用情况: 新数据多, 场景相似度高, 可以基于原模型重新训练 2.特征…...

克里金插值(Kriging interpolation)

原理可参考该文件&#xff1a;克里金(Kriging)插值的原理与公式推导 - xg1990 matlab code可参考&#xff1a;Ordinary Kriging - File Exchange - MATLAB Central Some notes: 采用普通克里金时&#xff0c;采样的密度对结果影响非常大。若采样密度不够&#xff0c;误差会非…...

sealed class-kotlin中的封闭类

在 Kotlin 中&#xff0c;sealed class&#xff08;密封类&#xff09;是一种特殊的类&#xff0c;用于限制继承的类的数量。密封类可以被用来表示一组有限的类型&#xff0c;通常用于状态管理或表达多种可能的错误类型。 密封类用 sealed 关键字定义&#xff0c;这意味着只能…...

MongoDB Shell 基本命令(一)

MongoDB Shell 基本命令(一&#xff09; 1. 基本概念 SQL术语/概念MongoDB术语/概念解释/说明databasedb数据库tablecollection数据库表/集合rowdocument数据记录行/文档columnfield数据字段/域indexindex索引table joins表连接,MongoDB不支持primary keyprimary key主键,Mon…...

Flink时间语义和时间窗口

前言 在实际的流计算业务场景中&#xff0c;我们会发现&#xff0c;数据和数据的计算往往都和时间具有相关性。 举几个例子&#xff1a; 直播间右上角通常会显示观看直播的人数&#xff0c;并且这个数字每隔一段时间就会更新一次&#xff0c;比如10秒。电商平台的商品列表&a…...

在wpf中登录成功之后怎么设置主页布局及点击不同的菜单跳转到不同的页面,这个是我们做wpf项目必要会的一个功能

通过frame与page实现在mvvm下的页面跳转 在wpf中登录成功之后怎么设置主页布局及点击不同的菜单跳转到不同的页面_哔哩哔哩_bilibili 1、MainWindow代码 <DockPanel><StackPanel DockPanel.Dock"Top" Height"40"><Grid><Grid.ColumnD…...

基于opencv的人脸闭眼识别疲劳监测

1. 项目简介 本项目旨在实现基于眼部特征的眨眼检测&#xff0c;通过监测眼睛开闭状态来计算眨眼次数&#xff0c;从而应用于疲劳监测、注意力检测等场景。使用了面部特征点检测算法&#xff0c;以及眼部特征比率&#xff08;EAR, Eye Aspect Ratio&#xff09;来判断眼睛的闭…...

aeo认证需要什么材料

AEO&#xff08;Authorized Economic Operator&#xff09;认证&#xff0c;即经认证的经营者认证&#xff0c;是企业信用管理体系的一种高级认证。申请AEO认证时&#xff0c;企业需要准备一系列的材料以证明其符合认证标准。以下是一份详细的AEO认证申请材料清单&#xff1a; …...

【iOS】YYModel

目录 什么是YYModel &#xff1f; 如何使用YYModel &#xff1f; 最简单的Model 与网络请求结合 属性为容器类的Model 白名单和黑名单 Model的嵌套 结语 什么是YYModel &#xff1f; YYModel是一个用于 iOS 和 macOS 开发的高性能的模型框架&#xff0c;主要用于对象和…...

Cadence元件A属性和B属性相互覆盖

最近在使用第三方插件集成到Cadence,协助导出BOM到平台上&#xff0c;方便对BOM进行管理和修改&#xff0c;结果因为属性A和属性B不相同&#xff0c;导致导出的BOM错误。如下图&#xff1a; ​​ 本来我们需要导出Q12&#xff0c;结果给我们导出了Q13&#xff0c;或者反之&…...

【火山引擎】语音合成 | HTTP接口 | 一次性合成 | python

目录 一 准备工作 二 HTTP接口(一次性合成-非流式) 1 接口说明 2 身份认证 3 请求方式 三 实践 四 注意事项 火山引擎语音合成TTS(Text-to-Speech)是一种基于云计算的语音合成服务,可以将文本转化为自然、流畅的语音。以下是火山引擎TTS的主要功能和特点: ①多种语音…...

YOLOv11改进-卷积-空间和通道重构卷积SCConv

本篇文章将介绍一个新的改进模块——SCConv&#xff08;小波空间和通道重构卷积&#xff09;&#xff0c;并阐述如何将其应用于YOLOv11中&#xff0c;显著提升模型性能。为了减少YOLOv11模型的空间和通道维度上的冗余&#xff0c;我们引入空间和通道重构卷积。首先&#xff0c;…...

记录一次从nacos配置信息泄露到redis写计划任务接管主机

经典c段打点开局。使用dddd做快速的打点发现某系统存在nacos权限绕过 有点怀疑是蜜罐&#xff0c;毕竟nacos这实在是有点经典 nacos利用 老规矩见面先上nacos利用工具打一波看看什么情况 弱口令nacos以及未授权访问&#xff0c;看这记录估计被光顾挺多次了啊 手动利用Nacos-…...

Unity加载界面制作

效果 UI部分 结构 说下思路: 因为是加载界面,所以最上层是一个Panel阻止所有的UI交互,这个Panel如果有图片就加一个图片,如果没有可以把透明度调到最大,颜色设为黑色. 下面最核心的就是一个进度条了,有图片的话,将进度条的底放进来,将进度条锚点设为下中,将滑动块的尺寸设为0.…...

最好的ppt模板网站是哪个?做PPT不可错过的18个网站!

现在有很多PPT模板网站&#xff0c;但真正免费且高质量的不多&#xff0c;今天我就分享主流的国内外PPT模板下载网站&#xff0c;并且会详细分析这些网站的优缺点&#xff0c;这些网站都是基于个人实际使用经验的&#xff0c;免费站点会特别标注&#xff0c;让你可以放心下载&a…...

煤矿安全监测监控作业题库

第一部分 安全法律法规知识子题库 单选题 1.《安全生产法》规定&#xff0c;生产经营单位应当向从业人员如实告知作业场所和工作岗位存在的(A)、防范措施以及事故应急措施。 A. 危险因素    B. 人员状况    C. 设备状况    D. 环境状况 2.《安全生产法》规定&…...

【记录】Django数据库的基础操作

数据库连接 在Django中使用 mysqlclient 这个包用于数据库的连接&#xff0c;切换至 Django环境中直接 pip install mysqlclient 安装此包 1 数据库连接配置 在项目目录下的setting.py中配置 DATABASES {default: {ENGINE: django.db.backends.mysql,NAME: mini,#数据库名US…...

XHCI 1.2b 规范摘要(五)

系列文章目录 XHCI 1.2b 规范摘要&#xff08;一&#xff09; XHCI 1.2b 规范摘要&#xff08;二&#xff09; XHCI 1.2b 规范摘要&#xff08;三&#xff09; XHCI 1.2b 规范摘要&#xff08;四&#xff09; XHCI 1.2b 规范摘要&#xff08;五&#xff09; 文章目录 系列文章目…...

为什么需要建设工程项目管理?工程项目管理有哪些亮点功能?

在建筑行业&#xff0c;项目管理的重要性不言而喻。随着工程规模的扩大、技术复杂度的提升&#xff0c;传统的管理模式已经难以满足现代工程的需求。过去&#xff0c;许多企业依赖手工记录、口头沟通和分散的信息管理&#xff0c;导致效率低下、成本失控、风险频发。例如&#…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

九天毕昇深度学习平台 | 如何安装库?

pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子&#xff1a; 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

【笔记】WSL 中 Rust 安装与测试完整记录

#工作记录 WSL 中 Rust 安装与测试完整记录 1. 运行环境 系统&#xff1a;Ubuntu 24.04 LTS (WSL2)架构&#xff1a;x86_64 (GNU/Linux)Rust 版本&#xff1a;rustc 1.87.0 (2025-05-09)Cargo 版本&#xff1a;cargo 1.87.0 (2025-05-06) 2. 安装 Rust 2.1 使用 Rust 官方安…...

Xela矩阵三轴触觉传感器的工作原理解析与应用场景

Xela矩阵三轴触觉传感器通过先进技术模拟人类触觉感知&#xff0c;帮助设备实现精确的力测量与位移监测。其核心功能基于磁性三维力测量与空间位移测量&#xff0c;能够捕捉多维触觉信息。该传感器的设计不仅提升了触觉感知的精度&#xff0c;还为机器人、医疗设备和制造业的智…...

Spring Boot + MyBatis 集成支付宝支付流程

Spring Boot MyBatis 集成支付宝支付流程 核心流程 商户系统生成订单调用支付宝创建预支付订单用户跳转支付宝完成支付支付宝异步通知支付结果商户处理支付结果更新订单状态支付宝同步跳转回商户页面 代码实现示例&#xff08;电脑网站支付&#xff09; 1. 添加依赖 <!…...

Linux操作系统共享Windows操作系统的文件

目录 一、共享文件 二、挂载 一、共享文件 点击虚拟机选项-设置 点击选项&#xff0c;设置文件夹共享为总是启用&#xff0c;点击添加&#xff0c;可添加需要共享的文件夹 查询是否共享成功 ls /mnt/hgfs 如果显示Download&#xff08;这是我共享的文件夹&#xff09;&…...

C++ 类基础:封装、继承、多态与多线程模板实现

前言 C 是一门强大的面向对象编程语言&#xff0c;而类&#xff08;Class&#xff09;作为其核心特性之一&#xff0c;是理解和使用 C 的关键。本文将深入探讨 C 类的基本特性&#xff0c;包括封装、继承和多态&#xff0c;同时讨论类中的权限控制&#xff0c;并展示如何使用类…...

SOC-ESP32S3部分:30-I2S音频-麦克风扬声器驱动

飞书文档https://x509p6c8to.feishu.cn/wiki/SKZzwIRH3i7lsckUOlzcuJsdnVf I2S简介 I2S&#xff08;Inter-Integrated Circuit Sound&#xff09;是一种用于传输数字音频数据的通信协议&#xff0c;广泛应用于音频设备中。 ESP32-S3 包含 2 个 I2S 外设&#xff0c;通过配置…...