go使用context包避免goroutine泄露问题

Posted chenqionghe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了go使用context包避免goroutine泄露问题相关的知识,希望对你有一定的参考价值。

go是带内存自动回收的特性,因此内存一般不会泄漏。但是Goroutine确存在泄漏的情况,同时泄漏的Goroutine引用的内存同样无法被回收。

下面的程序中后台Goroutine向管道输入自然数序列,main函数中输出序列。但是当break跳出for循环的时候,后台Goroutine就处于无法被回收的状态了。

func main() {
    ch := func() <-chan int {
        ch := make(chan int)
        go func() {
            for i := 0; ; i++ {
                ch <- i
            }
        } ()
        return ch
    }()

    for v := range ch {
        fmt.Println(v)
        if v == 5 {
            break
        }
    }
}

我们可以通过context包来避免这个问题:

func main() {
    ctx, cancel := context.WithCancel(context.Background())

    ch := func(ctx context.Context) <-chan int {
        ch := make(chan int)
        go func() {
            for i := 0; ; i++ {
                select {
                case <- ctx.Done():
                    return
                case ch <- i:
                }
            }
        } ()
        return ch
    }(ctx)

    for v := range ch {
        fmt.Println(v)
        if v == 5 {
            cancel()
            break
        }
    }
}

当main函数在break跳出循环时,通过调用cancel()来通知后台Goroutine退出,这样就避免了Goroutine的泄漏。

 

以上是关于go使用context包避免goroutine泄露问题的主要内容,如果未能解决你的问题,请参考以下文章

一日一学_Go语言Context(设计及分析)

Go36-32-context.Context

Golang Context 包详解

go Goroutine泄露

Go Context 详解之终极无惑

Go Context 详解之终极无惑