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

Go并发模型与模式:context 上下文控制

在 Go 的并发编程中,goroutine 虽然轻量高效,但也容易“失控”——一旦启动就很难精确停止。为了控制并发协程的取消、超时、信号传递和生命周期管理,Go 官方引入了 context 包。


一、为什么需要 context?

假设一个请求需同时发起多个协程处理,如果客户端中断请求,你就需要及时关闭所有协程以节省资源。这就是 context 的典型应用场景:

  • • ✅ 控制 goroutine 生命周期
  • • ✅ 统一管理取消信号和超时
  • • ✅ 传递跨 API 层的数据

二、context 的基本使用

Go 提供四种常见 context 创建方式:

context.Background()      // 最初始的上下文,常用作根 context
context.TODO()            // 占位用,尚未确定如何传入 context 时使用
context.WithCancel(ctx)   // 可调用 cancel() 主动取消
context.WithTimeout(ctx, d)  // 指定超时时间
context.WithDeadline(ctx, t) // 指定截止时间

三、context.WithCancel 示例:主动取消

package mainimport ("context""fmt""time"
)func worker(ctx context.Context, name string) {for {select {case <-ctx.Done():fmt.Println(name, "被取消")returndefault:fmt.Println(name, "正在工作")time.Sleep(time.Second)}}
}func main() {ctx, cancel := context.WithCancel(context.Background())go worker(ctx, "worker1")go worker(ctx, "worker2")time.Sleep(3 * time.Second)cancel() // 通知所有携带该 context 的协程停止time.Sleep(1 * time.Second)
}

四、context.WithTimeout 示例:自动超时取消

func main() {ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)defer cancel()select {case <-time.After(5 * time.Second):fmt.Println("任务完成")case <-ctx.Done():fmt.Println("超时取消:", ctx.Err())}
}

五、在 channel 模式中使用 context 控制 goroutine

结合 channel 和 worker pool:

func worker(ctx context.Context, jobs <-chan int, results chan<- int) {for {select {case <-ctx.Done():returncase job, ok := <-jobs:if !ok {return}results <- job * 2}}
}

六、context 的值传递功能

context 还可以在多个函数间传递一些只读值(例如:请求 ID、用户 token 等):

ctx := context.WithValue(context.Background(), "trace_id", "abc123")
doSomething(ctx)func doSomething(ctx context.Context) {traceID := ctx.Value("trace_id")fmt.Println("Trace ID:", traceID)
}

⚠️ 不推荐用它来传递业务参数,仅用于日志追踪、认证信息等不可变值


七、最佳实践与注意事项

建议描述
✅ 统一根 context每个服务入口处使用 context.Background() 或 context.TODO()
✅ 及时调用 cancel()否则 goroutine 不会释放,造成泄露
✅ 在 goroutine 内监听 ctx.Done()接收到取消信号后及时退出
⚠️ 避免 context.Value 滥用只传递与请求作用域相关的元信息

八、小结

  • • context 是 Go 并发模型中重要的资源控制机制;
  • • 能有效解决 goroutine 泄漏、超时处理、取消信号问题;
  • • 与 goroutine + channel 搭配使用,可以构建健壮的并发系统。

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

相关文章:

  • 01.pycharm整合conda
  • 华为OD最新机试真题-对称美学-OD统一考试(B卷)
  • WinForm中实现Adobe PDF Reader实现旋转PDF功能
  • opencv vs2020正确的环境配置
  • 《HarmonyOSNext终极UIAbility手册:从启动模式到页面跳转,一网打尽!》
  • 菌菇食用攻略:从营养解析到安全指南,解锁科学食菌
  • 【JavaEE】-- HTTPS
  • 【Web】腾讯云 COS 静态网站部署与自定义域名 HTTPS 全流程
  • 【C++】来学习使用set和map吧
  • Python毕业设计226—基于python+爬虫+html的豆瓣影视数据可视化系统(源代码+数据库+万字论文)
  • 基于鸿蒙 HarmonyOS 5 打车小程序案例
  • 深入偏微分方程的世界-AI云计算
  • 金属工具制造企业如何做项目管理?数字化系统全面提升交付效率
  • 使用反汇编指令javap查看synchronized实现原理
  • Keepalived 与 Nginx 高可用部署方案详解
  • 【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表
  • ROS move base 简易调试
  • 使用智能表格做项目工时管理
  • 软件开发和嵌入式开发岗位的面试题
  • 【深尚想】SN74HCT244DWR缓冲器/驱动器TI逻辑芯片 电子元器件解析
  • 【题解】P1156 垃圾陷阱
  • “新京味”小柯音乐剧《三里屯42》 在小柯剧场6月全新开演
  • Oraclede 的体系结构
  • pycharm-continue插件久后使用的注意事项
  • Java是实现大根堆
  • Unreal从入门到精通之 碰撞响应 详解
  • 【JavaScript】 HTTP Cookie 核心知识梳理与常用的封装实现
  • 数字孪生城市崛起:智慧城市生态中的技术协同与治理变革
  • DSP使用三角函数问题
  • 卷积神经网络参数量计算