zoukankan      html  css  js  c++  java
  • 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的泄漏。

  • 相关阅读:
    springBoot 与 springMVC的区别
    spring的IOC和AOP
    实现同步的三种方法
    台阶积水问题
    requsets模块和beautifulsoup模块
    爬虫
    rabbitMQ 消息队列
    Django框架
    mysql
    jQuery
  • 原文地址:https://www.cnblogs.com/chenqionghe/p/9769351.html
Copyright © 2011-2022 走看看