首页 > 其他分享 >golang中goroutine泄漏的问题以及解决方案

golang中goroutine泄漏的问题以及解决方案

时间:2022-12-25 11:13:59浏览次数:53  
标签:泄漏 goroutine ctx golang 任务 context time 超时 子协

参考文章

Golang中的goroutine泄漏问题

如何退出协程 goroutine (超时场景)

如何退出协程 goroutine (其他场景)

问题纠正

之前视频讲过一个知识点,如何设置子协裎超时机制,其实像下面这段代码,主协裎关闭后子协裎是不会停止的:

func TestZ92(t *testing.T) {

    // 超时时间为1秒的ctx
    ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second*1))
    defer cancel()

    // 超时的子任务
    go func(ctx context.Context) {
        // 子任务执行3秒
        fmt.Println("子协裎任务开始执行!")
        // Notice 已经在执行的这个任务没有办法立刻退出!
        time.Sleep(time.Second * 3)
        fmt.Println("子协裎任务执行完成!")
    }(ctx)

    select {
    case <-ctx.Done():
        fmt.Println("主协裎的ctx已经完成!")
        // case <-time.After(time.Duration(time.Second * 5)):
        //     fmt.Println("timeout!!!")
        //     return
    }

    time.Sleep(time.Second * 6)

    fmt.Println("主协裎关闭!!!")
}
View Code

打印的结果如下(可以看到,虽然把ctx传进去但是没有用,主协裎由于超时关闭了,子协裎还在执行~):

子协裎任务开始执行!
主协裎的ctx已经完成!
子协裎任务执行完成!
主协裎关闭!!!

可以做如下修改:

func TestZ92(t *testing.T) {

    // 超时时间为1秒的ctx
    ctx, cancel := context.WithTimeout(context.Background(), time.Duration(time.Second*1))
    defer cancel()

    // 超时的子任务
    go func(ctx context.Context) {
        // 子任务执行3秒
        fmt.Println("子协裎任务开始执行!")
        // Notice 已经在执行的这个任务没有办法立刻退出!
        time.Sleep(time.Second * 3)
        // Notice 在耗时操作后面判断一下,如果ctx已经Done了,就不往下执行了!!!
        select {
        case <-ctx.Done():
            return
        }
        fmt.Println("子协裎任务执行完成!")
    }(ctx)

    select {
    case <-ctx.Done():
        fmt.Println("主协裎的ctx已经完成!")
        // case <-time.After(time.Duration(time.Second * 5)):
        //     fmt.Println("timeout!!!")
        //     return
    }

    time.Sleep(time.Second * 6)

    fmt.Println("主协裎关闭!!!")
} 

123

123

123

标签:泄漏,goroutine,ctx,golang,任务,context,time,超时,子协
From: https://www.cnblogs.com/paulwhw/p/17003763.html

相关文章

  • 新版以太坊Ethereum库ethersV5.0配合后端Golang1.18实时链接区块链钱包(Metamask/Okc)
    区块链去中心化思想无处不在,比如最近使用个体抗原自检替代大规模的中心化核酸检测,就是去中心化思想的落地实践,避免了大规模聚集导致的交叉感染,提高了检测效率,本次我们使用E......
  • golang在win10安装、环境配置 和 goland(IDE开发golang配置)
    前言本人在使用goland软件开发go时,对于goland软件配置网上资料少,为了方便自己遗忘、也为了希望和我一样的小白能够更好的使用,所以就写下这篇博客,废话不多说开考。一、查......
  • Go 快速入门指南 - goroutine
    概述goroutine是Go程序并发执行的实体,对于初学者来讲,可以简单地将 ​​goroutine​​​ 理解为一个 ​​超轻量的线程​​。当一个程序启动时,只有一个goroutine调用......
  • Go-19 Golang结构体和JSON相互序列化和反序列化
    packagemainimport( "encoding/json" "fmt")//Golang结构体和Json相互转换 序列化和反序列化typeStudentstruct{ IDint Genderstring namestri......
  • 内存泄漏、块级格式化上下文、语义化标签的作用
    一、内存泄漏?定义:申请到的一块内存既不能被使用,也不能被回收,直到浏览器进程结束。哪些常见的内存泄漏?1.意外的全局变量一个函数体内的变量没有使用var或let关键字......
  • Go 快速入门指南 - goroutine
    概述goroutine是Go程序并发执行的实体,对于初学者来讲,可以简单地将 goroutine 理解为一个 超轻量的线程。当一个程序启动时,只有一个goroutine调用main函数,称为......
  • Go-18 Golang结构体struct详解
    packagemainimport"fmt"//Golang中的结构体详解typenewIntint//自定义类型typemyInt=int//类型别名typezsIntinttypepersonstruct{ namestr......
  • 用c++代码实现golang里面的map数据类型
    因为之前写过一篇golang数据类型分析的文章。包含slice、map、channel等。想写一篇用其它语言实现golang数据类型的代码,于是选中map作为实验对象。笔者之前写过5年的c++,......
  • 微服务-限流整流之golang RateLimiter
    前言分布式环境下应对高并发保证服务稳定,优先级从高到低分别为缓存、限流、降级、熔断,本文重点就讲讲限流这部分。其实服务降级、熔断本身也是限流的一种,因为它们本质上......
  • 【Golang 快速入门】项目实战:即时通信系统
     Golang快速入门即时通信系统-服务端版本一:构建基础Server版本二:用户上线功能版本三:用户消息广播机制版本四:用户业务层封装版本五:在线用户查询版本六:修......