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

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.dtcms.com/a/327214.html

相关文章:

  • Rust学习笔记(二)|变量、函数与控制流
  • 【七指共振擒牛战法】副图+选股指标——多维度捕捉主升浪的量化交易利器
  • 智慧校园|智慧校园管理小程序|基于微信小程序的智慧校园管理系统设计与实现(源码+数据库+文档)
  • [Robotics_py] 定位滤波器 | 预测与更新 | 扩展卡尔曼滤波器(`EKF`)
  • Linux操作系统应用软件编程——标准IO
  • Java Stream ReduceOps
  • 负载均衡详解
  • 小程序排名优化:用户行为数据背后的提升密码
  • PostgreSQL 范围、空间唯一性约束
  • 「ECG信号处理——(23)基于ECG和PPG信号的血压预测」2025年8月12日
  • SQL 生成日期与产品的所有组合:CROSS JOIN(笛卡尔积)
  • Linux 系统运维、网络、SQL Server常用命令
  • 机器学习 [白板推导](九)[变分推断]
  • DRAM、SRAM、NAND Flash、NOR Flash、EEPROM、MRAM存储器你分得清吗?
  • 用pom文件从nexus3拉依赖,无法拉取的一个问题
  • 逻辑删除 vs 物理删除:MyBatis-Plus 实现指南与实践
  • 可泛化逻辑推理Python编程作为医疗AI发展方向研究
  • 关于数据库的restful api接口工具SqlRest的使用
  • 如何在 Ubuntu 24.04 LTS Linux 中安装 JSON Server
  • 2025年国赛新规解读:8-12最新发布文件
  • 初识数据结构——优先级队列(堆!堆!堆!)
  • 偶遇冰狐智能辅助的录音
  • Python初学者笔记第二十四期 -- (面向对象编程)
  • 教程 | 用Parasoft SOAtest实现高效CI回归测试
  • 从零到一的 Python CI/CD 实战指南:用 GitHub Actions 与 Jenkins 打造稳定、可持续交付的工程力
  • 下一代防火墙技术
  • 【ad-hoc 最小生成树 构造】P8957 「CGOI-3」巫泡弹弹乐|普及+
  • 【Redis在智能健身镜中的作用:运动指导与用户数据同步】
  • 计算机网络摘星题库800题笔记 第6章 应用层
  • 使用正则中的sub实现获取我们匹配的字符串,然后追加指定字符