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

Golang 语言中 Context 的使用方式

一、介绍

        在Golang 语言并发编程中,经常会遇到监控 goroutine 运行结束的场景,通常我们会想使用WaitGroup 和 chan + select , 其中WaitGroup 用于监控一组goroutine 是否全部运行结束,chan + select 用于监控一个 goroutine 是否运行结束(取消一个 goroutine )

        如果我们需要监控多个goroutine 是否运行结束,或者 取消多个。通常会使用context ,当然使用context 也可以用于监控一个 goroutine 是否运行结束。

二、取消一个 goroutine

        使用context 取消一个 goroutine ,比较类似实用 chan   + select  的方式取消一个 goroutine

示例代码:

package mainimport ("context""fmt""time"
)func main() {ctx, cancel := context.WithCancel(context.Background())go func(ctx context.Context) {for {select {case <-ctx.Done():fmt.Println("goroutine  已停止")returndefault:fmt.Println("goroutine 正在运行")time.Sleep(time.Second)}}}(ctx)time.Sleep(time.Second * 5)cancel()time.Sleep(time.Second * 5)fmt.Println("goroutine 已结束")
}

运行结果:

        阅读上面这段代码,我们首先使用 context.Background() 创建一个context 树的根节点,然后使用context.WithCancel() 创建一个可取消的走context 类型的变量,ctx ,作为参数传递给子goroutine ,用作跟踪子goroutine 。

        然后在子 goroutine 中使用for select 监控 <- ctx.Done() 判断goroutine 是否运行结束。

        最后使用 context.Withcancel() 返回的第二个值CancelFunc 类型的cancel 变量给子goroutine 发送取消指令

三、取消多个goroutine

下面,我们再来看看一个使用context 停止多个goroutine 的示例

package mainimport ("context""fmt""time"
)func main() {ctx, cancel := context.WithCancel(context.Background())go worker(ctx, "节点一")go worker(ctx, "节点二")go worker(ctx, "节点三")go worker(ctx, "节点四")time.Sleep(time.Second * 5)cancel()time.Sleep(time.Second * 5)fmt.Println("main  goroutine  已结束")
}func worker(ctx context.Context, node string) {for {select {case <-ctx.Done():fmt.Println(node, "goroutine 已停止")returndefault:fmt.Println(node, "goroutine  正在运行")time.Sleep(time.Second)}}
}

运行结果:

阅读上面这段代码,我们使用go 关键字启动三个 worker goroutine ,和上个示例一样,首先创建一个context  树的节点,使用第一个返回值context 类型的字ctx  跟踪每一个worker goroutine ,在worker 中使用for select 监控 <- ctx.Done() 判断子 goroutine 是否运行结束,通过调用第二份返回值CancelFunc 类型cancel 给子goroutine 发送取消指令,此时所有字context 都会接受到取消指令,goroutine 结束运行

四、上下文信息传递

        我们在前面的示例中使用WithCancel  函数,用作取消context,除此之外,可用作取消Context 的函数还有WithDeadline 函数和WithTimeout 函数,分别用于定时取消和超时取消;在Golang中 context 包还有一个重要的作用,就是作用上下文传递,请看示例代码:

package mainimport ("context""fmt""time"
)func main() {ctx, cancel := context.WithCancel(context.Background())// 传递上下文信息ctxValue := context.WithValue(ctx, "uid", 1)go func(ctx context.Context) {for {select {case <-ctx.Done():fmt.Println(ctx.Value("uid"), "goroutine 已停止")returndefault:fmt.Println("goroutine  正在运行")time.Sleep(time.Second)}}}(ctxValue)time.Sleep(time.Second * 5)cancel()time.Sleep(time.Second * 5)fmt.Println("main goroutine 已结束")}

运行结果:

        阅读上面的代码,我们使用了 WithValue 函数给子级 goroutine 传递上下文信息uid.。 WithValue 函数接收三个参数,分别是parent context ,key 和value 。返回值是一个context ,我们可以在子级 goroutine 中调用Value 方法获取传递的上下文信息。

http://www.xdnf.cn/news/17604.html

相关文章:

  • 计算机视觉(6)-自动驾驶感知方案对比
  • AV、IPS、WAF对比
  • CMake笔记:PUBLIC/PRIVATE/INTERFACE的使用
  • 力扣经典算法篇-50-单词规律(双哈希结构+正反向求解)
  • 微软发布GPT-5赋能的Copilot:重构办公场景的智能革命
  • 【昇腾】关于Atlas 200I A2加速模块macro0配置3路PCIE+1路SATA在hboot2中的一个bug_20250812
  • TensorBoard的使用 小土堆pytorch记录
  • 猫头虎AI分享|腾讯新开源了一个轻量级、即插即用的身份保留视频生成框架:Stand-In,也支持换头像视频
  • PostgreSQL 范围、空间唯一性约束
  • Linux 常用命令大全:覆盖日常 99% 操作需求
  • UserController类讲解
  • 2025年Java后端秋招面试宝典:高频题库+场景解析
  • 国产3D大型装配设计新突破②:装配约束智能推断 | 中望3D 2026
  • 【Redis与缓存预热:如何通过预加载减少数据库压力】
  • Ansible 基本使用
  • 02-Ansible 基本使用
  • Day 38: Dataset类和DataLoader类
  • 计算机网络摘星题库800题笔记 第5章 传输层
  • 达梦数据闪回查询-快速恢复表
  • 燕山大学计算机网络实验(2025最新)
  • SpringMVC的原理及执行流程?
  • uv 配置和简单使用
  • 飞算JavaAI全流程实操指南:从需求到部署的智能开发体验
  • 虚拟机高级玩法-网页也能运行虚拟机——WebAssembly
  • code-inspector-plugin插件
  • [ue5 shader] 路由申明和路由引用
  • 【SpringBoot】05 容器功能 - SpringBoot底层注解的应用与实战 - @Configuration + @Bean
  • 智能家居Agent:物联网设备的统一控制与管理
  • 无人机航拍数据集|第13期 无人机城市斑马线目标检测YOLO数据集963张yolov11/yolov8/yolov5可训练
  • 无人机智能返航模块技术分析