GOland的context的使用

超时控制

在 HTTP 请求、数据库查询或 RPC 调用等操作中,防止请求长时间阻塞。

package mainimport ("context""fmt""time"
)func main() {// 设置 2 秒超时ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)defer cancel() // 确保超时后释放资源result := make(chan string)go func() {time.Sleep(3 * time.Second) // 模拟耗时任务result <- "任务完成"}()select {case res := <-result:fmt.Println(res)  // 如果 `result` 先返回数据,就打印结果case <-ctx.Done():fmt.Println("任务超时,取消操作") // 如果 `ctx.Done()` 先触发,说明超时了}
}

context.WithTimeout() 允许在设定时间后自动取消操作,避免 goroutine 长时间阻塞

手动取消

如果一个主 goroutine 需要通知子 goroutine 停止执行,可以使用 context.WithCancel()

package mainimport ("context""fmt""time"
)func worker(ctx context.Context) {for {select {case <-ctx.Done():fmt.Println("收到取消信号,退出")returndefault:fmt.Println("工作中...")time.Sleep(500 * time.Millisecond)}}
}func main() {ctx, cancel := context.WithCancel(context.Background())go worker(ctx)time.Sleep(2 * time.Second)fmt.Println("取消任务")cancel() // 发送取消信号time.Sleep(1 * time.Second) // 等待 goroutine 退出
}在 TCP 服务器中,我们可能需要在主程序退出时,通知所有客户端断开连接。package mainimport ("context""fmt""net""time"
)func handleConnection(ctx context.Context, conn net.Conn) {defer conn.Close()for {select {case <-ctx.Done():fmt.Println("断开客户端连接:", conn.RemoteAddr())returndefault:time.Sleep(1 * time.Second) // 模拟处理fmt.Println("服务客户端:", conn.RemoteAddr())}}
}func main() {ctx, cancel := context.WithCancel(context.Background())ln, err := net.Listen("tcp", ":8080")if err != nil {fmt.Println("监听失败:", err)return}defer ln.Close()go func() {for {conn, err := ln.Accept()if err != nil {fmt.Println("接受连接失败:", err)continue}go handleConnection(ctx, conn)}}()time.Sleep(10 * time.Second) // 服务器运行 10 秒fmt.Println("关闭服务器,断开所有连接")cancel() // 发送取消信号,所有连接都会断开time.Sleep(2 * time.Second) // 等待 goroutine 退出fmt.Println("服务器已关闭")
}

context.WithCancel() 适用于 任务需要手动终止 的场景,如定期任务、消息队列消费等。

传递请求作用域的数据

可以用 context.WithValue() 传递 请求相关的元数据,比如 用户身份信息、trace ID

package mainimport ("context""fmt"
)// 定义一个键的类型,避免键冲突
type contextKey stringfunc processRequest(ctx context.Context) {uid := ctx.Value(contextKey("userID"))fmt.Println("处理请求的用户 ID:", uid)
}func main() {ctx := context.WithValue(context.Background(), contextKey("userID"), 12345)processRequest(ctx)
}

context.WithValue() 适用于 日志追踪、用户身份验证 等场景,但不建议传递大数据结构(会影响性能)。

与 HTTP 服务器结合

在 Web 服务器中,Go 的 http.Request 自带 Context() 方法,可以获取请求的 context,用于控制请求生命周期

package mainimport ("context""fmt""net/http""time"
)func handler(w http.ResponseWriter, r *http.Request) {ctx := r.Context()fmt.Println("处理请求")select {case <-time.After(3 * time.Second):fmt.Fprintln(w, "请求处理完成")case <-ctx.Done():fmt.Fprintln(w, "请求取消")}
}func main() {http.HandleFunc("/", handler)server := &http.Server{Addr: ":8080",}go func() {time.Sleep(2 * time.Second)server.Shutdown(context.Background()) // 2 秒后关闭服务器}()fmt.Println("服务器启动在 8080 端口")if err := server.ListenAndServe(); err != nil {fmt.Println("服务器已关闭")}
}

当客户端断开连接,ctx.Done() 会触发,避免继续执行无用的操作。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/69487.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CANoe查看CAN报文发送周期

在CANoe软件中&#xff0c;Analysis -> Select other options 下的 Toggle Grid 和 Toggle Samples 选项确实用于控制分析窗口中的显示方式和采样行为&#xff0c;从而更清晰地查看CAN报文周期。 Toggle Grid&#xff08;切换网格&#xff09; 功能&#xff1a;启用网格线…

【Go语言圣经】第八节:Goroutines和Channels

DeepSeek 说 Goroutines 和 Channels 最近非常流行询问DeepSeek某些相关概念或热点的解释&#xff0c;因此在开始系统性地学习《Go语言圣经》之前&#xff0c;我首先向DeepSeek进行了提问。具体的Prompt如下&#xff1a; 有关Golang当中的Goroutines和Channels&#xff0c;我现…

e2studio开发RA4M2(10)----定时器AGT输出PWM

e2studio开发RA4M2.10--定时器AGT输出PWM 概述视频教学样品申请硬件准备参考程序源码下载选择计时器新建工程工程模板保存工程路径芯片配置工程模板选择时钟设置SWD调试口设置GPIO口配置AGT定时器AGT定时器属性配置初始化AGT启动AGT PWM模块AGTIO 和 AGTO演示 概述 AGT模块是R…

使用PyCharm进行Django项目开发环境搭建

如果在PyCharm中创建Django项目 1. 打开PyCharm&#xff0c;选择新建项目 2.左侧选择Django&#xff0c;并设置项目名称 3.查看项目解释器初始配置 4.新建应用程序 执行以下操作之一&#xff1a; 转到工具| 运行manage.py任务或按CtrlAltR 在打开的manage.pystartapp控制台…

【Java基础】为什么不支持多重继承?方法重载和方法重写之间区别、Exception 和 Error 区别?

Hi~&#xff01;这里是奋斗的明志&#xff0c;很荣幸您能阅读我的文章&#xff0c;诚请评论指点&#xff0c;欢迎欢迎 ~~ &#x1f331;&#x1f331;个人主页&#xff1a;奋斗的明志 &#x1f331;&#x1f331;所属专栏&#xff1a;Java基础面经 &#x1f4da;本系列文章为个…

bladeX微服务框架如何修改nacos分组

nacos中注册的服务他的分组&#xff08;分组名称&#xff09;怎么修改 在org.springblade.common.launch // 指定注册IP PropsUtil.setProperty(props, "spring.cloud.nacos.discovery.ip", "127.0.0.1"); // 指定注册端口 PropsUtil.setProperty(props, &…

大数据项目2a:基于spark的电影推荐和分析系统设计与实现

1、项目目的 本项目的目的是设计并实现一个基于Spark的电影推荐系统&#xff0c;以应对大数据环境下电影推荐服务的挑战。通过整合电影、评分和用户数据集&#xff0c;并利用SparkSql框架进行高效处理&#xff0c;系统能够为用户提供个性化的电影推荐。项目采用多种先进技术&…

机器学习常用包matplotlib篇(四)绘图规范

前言 为了让 Matplotlib 绘图代码更规范、易读&#xff0c;且为后期图形完善预留空间&#xff0c;建议遵循一些规范绘图方法。&#x1f609; 1.管理图形对象 建议使用 plt.figure() 或者 plt.subplots() 管理完整的图形对象&#xff0c;而非直接用 plt.plot(...) 绘图。这样能…

LVGL4种输入设备详解(触摸、键盘、实体按键、编码器)

lvgl有触摸、键盘、实体按键、编码器四种输入设备 先来分析一下这四种输入设备有什么区别 &#xff08;1&#xff09;LV_INDEV_TYPE_POINTER 主要用于触摸屏 用到哪个输入设备保留哪个其他的也是&#xff0c;保留触摸屏输入的任务注册&#xff0c;其它几种种输入任务的注册&…

5G技术解析:从核心概念到关键技术

1. 引言 5G技术的迅猛发展正在重塑我们的生活方式和社会结构。它不仅仅是新一代的移动通信技术&#xff0c;更是一场深刻的技术革命。5G网络正在以其惊人的高速、低延迟和大带宽能力&#xff0c;为智能家居、自动驾驶、工业自动化、远程医疗等另一带来前所未有的可能性。 本文…

背包问题1

核心&#xff1a; // f[i][j] 表示只看前i个物品&#xff0c;总体积是j的情况下&#xff0c;总价值是多少 //res maxx(f[n][]0-v] //f[i][j]: //1 不选第i个物品 f[i][j] f[i-1][j] //2 选第i个物品 f[i][j] f[i-1][j-v[i]] w[i]

Redis | 十大数据类型

文章目录 十大数据类型概述key操作命令数据类型命令及落地运用redis字符串&#xff08;String&#xff09;redis列表&#xff08;List&#xff09;redis哈希表&#xff08;Hash&#xff09;redis集合&#xff08;Set&#xff09;redis有序集合&#xff08;ZSet / SortedSet&…

DeepSeek图解10页PDF

以前一直在关注国内外的一些AI工具&#xff0c;包括文本型、图像类的一些AI实践&#xff0c;最近DeepSeek突然爆火&#xff0c;从互联网收集一些资料与大家一起分享学习。 本章节分享的文件为网上流传的DeepSeek图解10页PDF&#xff0c;免费附件链接给出。 1 本地 1 本地部…

C# OpenCvSharp 部署MOWA:多合一图像扭曲模型

目录 说明 效果 项目 代码 下载 参考 C# OpenCvSharp 部署MOWA&#xff1a;多合一图像扭曲模型 说明 算法模型的paper名称是《MOWA: Multiple-in-One Image Warping Model》 ariv链接 https://arxiv.org/pdf/2404.10716 效果 Stitched Image 翻译成中文意思是&…

vite+vue3搭建前端项目并使用 Bulma 框架

vitevue3搭建前端项目并使用 Bulma 框架 bluma css框架参照。 https://bulma.org.cn/documentation/start/overview/ 1. 创建项目 npm init vitelatest ai-imageneration --template vue选择 vue 和 typescript 作为模板&#xff1a; 2. 安装依赖 npm install npm install…

Spring 6.2.2 @scope(“prototype“)原理

Spring Prototype 原理&#xff1f; 前置准备 创建一个MyService类 Scope("prototype") Service("myService") public class MyService {public String getMessage() {return "Hello, World!";} }创建一个main类&#xff0c;用于debug。 pr…

RabbitMQ 可靠性投递

文章目录 前言一、RabbitMQ自带机制1、生产者发送消息注意1.1、事务&#xff08;Transactions&#xff09;1.2、发布确认&#xff08;Publisher Confirms&#xff09;1.2.1、同步1.2.2、异步 2、消息路由机制2.1、使用备份交换机&#xff08;Alternate Exchanges&#xff09;2.…

【实用技能】如何借助3D文档控件Aspose.3D, 在Java中无缝制作 3D 球体

概述 创建 3D 球体是 3D 图形设计的一个基本方面。无论您是在开发游戏、模拟还是可视化&#xff0c;无缝创建 3D 球体模型的能力都至关重要。Aspose.3D通过提供强大的 3D 图形 SDK 在各个行业中发挥着重要作用。它允许开发人员轻松创建、操作和转换 3D 模型。此 SDK 对于希望将…

C语言基础系列【3】VSCode使用

前面我们提到过VSCode有多么的好用&#xff0c;本文主要介绍如何使用VSCode编译运行C语言代码。 安装 首先去官网&#xff08;https://code.visualstudio.com/&#xff09;下载安装包&#xff0c;点击Download for Windows 获取安装包后&#xff0c;一路点击Next就可以。 配…

windows安装WSL完整指南

本文首先介绍WSL&#xff0c;然后一步一步安装WSL及Ubuntu系统&#xff0c;最后讲解如何在两个系统之间访问和共享文件信息。通过学习该完整指南&#xff0c;能帮助你快速安装WSL&#xff0c;解决安装和使用过程中的常见问题。 理解WSL&#xff08;Windows Subsystem for Linux…