Go技巧:用Context包优雅管理goroutine生命周期

简介: Go技巧:用Context包优雅管理goroutine生命周期

Go技巧:用Context包优雅管理goroutine生命周期

在Go并发编程中,goroutine的启动很简单,但如何优雅地停止它们却常被忽视。今天分享一个使用context.Context管理goroutine生命周期的实用技巧。

问题场景

假设我们有一个执行任务的goroutine,需要在主程序退出前或用户取消操作时立即停止:

func worker() {
   
    for {
   
        // 模拟耗时操作
        time.Sleep(time.Second)
        fmt.Println("working...")
    }
}

这种写法无法从外部控制goroutine的退出,会造成goroutine泄漏。

解决方案:Context + select

利用context.Contextselect语句,可以优雅地实现超时控制和主动取消:

func worker(ctx context.Context) {
   
    for {
   
        select {
   
        case <-ctx.Done():
            fmt.Println("worker stopped:", ctx.Err())
            return
        default:
            // 执行实际工作
            time.Sleep(time.Second)
            fmt.Println("working...")
        }
    }
}

func main() {
   
    ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
    defer cancel() // 确保资源释放

    go worker(ctx)

    // 模拟用户按任意键退出
    fmt.Scanln()
    cancel() // 手动取消
}

关键点解析

  1. ctx.Done():返回一个只读channel,当context被取消或超时时会关闭
  2. select语句:同时监听工作逻辑和取消信号,谁先到达就执行谁
  3. defer cancel():即使函数正常返回,也要确保调用cancel释放资源

进阶用法:传递元数据

Context还可以传递请求相关的元数据:

ctx := context.WithValue(context.Background(), "requestID", "req-123")

但在生产代码中,建议将必要参数显式传递,而非依赖context.Value。

总结

使用context管理goroutine生命周期是Go的最佳实践之一。它让你的并发代码更加健壮、可控,避免了资源泄漏和难以调试的并发问题。

记住:创建goroutine时,就要想清楚如何停止它

目录
相关文章
|
算法 API UED
基于Gin框架的HTTP接口限速实践
基于Gin框架的HTTP接口限速实践
525 0
|
5月前
|
存储 安全 算法
ThreadLocal 90% 开发者都踩过的坑:底层原理拆解、内存泄漏根治与架构级用法全解
本文深度解析ThreadLocal底层原理(JDK17源码级),直击多线程上下文串号、线程池OOM、traceId传递失效等高频痛点,详解内存泄漏本质(弱引用实为兜底优化)、根治方案(强制remove)及TTL等生产级实践,涵盖用户/trace/事务/数据源四大上下文场景与七大避坑指南。
600 2
|
XML Java 数据格式
深入探索Spring的Bean注入:四种方式解析与循环依赖探讨
深入探索Spring的Bean注入:四种方式解析与循环依赖探讨
508 0
|
存储 数据采集 数据挖掘
Python数据分析实验一:Python数据采集与存储
Python数据分析实验一:Python数据采集与存储
|
人工智能 JavaScript 前端开发
借助 CodeBuddy,我轻松开发出三分钟读书 App
借助 CodeBuddy,我轻松开发出三分钟读书 App
415 6
|
前端开发 Java 数据库
玩转springboot之springboot注册servlet
在Spring Boot中注册Servlet非常灵活,可以通过 `@WebServlet`注解快速注册,也可以通过 `ServletRegistrationBean`进行细粒度控制。通过这两种方式,可以满足各种场景下的需求,确保应用能够高效处理HTTP请求。
1433 14
|
SQL 关系型数据库 数据管理
在 Postgres 中使用 Delete Join
【8月更文挑战第11天】
944 0
在 Postgres 中使用 Delete Join
|
前端开发 JavaScript 定位技术
三、前端高德地图、测量两个点之前的距离
文章介绍了如何在前端使用高德地图API实现测量两个点之间的距离,包括开启和关闭测量工具的方法,以及如何清除地图上的测量点、连线和文字。
1021 2
三、前端高德地图、测量两个点之前的距离
|
消息中间件 Go API
Golang深入浅出之-Go语言中的微服务架构设计与实践
【5月更文挑战第4天】本文探讨了Go语言在微服务架构中的应用,强调了单一职责、标准化API、服务自治和容错设计等原则。同时,指出了过度拆分、服务通信复杂性、数据一致性和部署复杂性等常见问题,并提出了DDD拆分、使用成熟框架、事件驱动和配置管理与CI/CD的解决方案。文中还提供了使用Gin构建HTTP服务和gRPC进行服务间通信的示例。
1328 0

热门文章

最新文章