go使用context包避免goroutine泄露問題

go是帶內存自動回收的特性,所以內存通常不會泄漏。可是Goroutine確存在泄漏的狀況,同時泄漏的Goroutine引用的內存一樣沒法被回收。函數

下面的程序中後臺Goroutine向管道輸入天然數序列,main函數中輸出序列。可是當break跳出for循環的時候,後臺Goroutine就處於沒法被回收的狀態了。blog

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的泄漏。it

相關文章
相關標籤/搜索