我是靠谱客的博主 等待母鸡,最近开发中收集的这篇文章主要介绍什么是goroutine leak?,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

goroutine leak,是go协程泄漏,什么是go协程泄漏,通俗来说,开启了一个goroutine,用完后,我们要正确让其结束。如果它没用了,还没结束,那就是goroutine leak。

泄漏的goroutine占用一部分cpu,还可能占着一些其他资源,从而影响主协程效率,有时甚至产生异常。

我们看下面的一个例子。

例子中我们的主协程需要通过某远程服务查询到一个结果。使用一个multiQuery的函数启动多个协程,分别向不同的服务器发起查询,只要收到一个服务器返回,multiQeury就返回结果。

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func queryFromSrc(src string) (ret string) {
    nanoSec := time.Now().Nanosecond()
    rand.Seed(int64(nanoSec))
    sec := (rand.Int31() % 10) + 1
    // time sleep simulates dns lookup and query
    time.Sleep(time.Second * time.Duration(sec))
    ret = fmt.Sprintf("src=%s use sec=%d", src, sec)
    fmt.Println("a query ok, ret=", ret)
    return ret
}

func multiQuery() (ret string) {
    res := make(chan string, 3)
    go func() {
        res <- queryFromSrc("ns1.dnsserver.com")
    }()
    go func() {
        res <- queryFromSrc("ns2.dnsserver.com")
    }()
    go func() {
        res <- queryFromSrc("ns3.dnsserver.com")
    }()
    return <-res
}

func main() {
    fmt.Println("start multi query:")
    res := multiQuery()
    fmt.Println("res=", res)
    //time.Sleep(time.Second * 20)
}

本案例使用了一个带缓冲区的channel,multiQuery中的三个并行go func不分先后从远程获取一个结果返回。获取的结果写入channel res,在第一个结果收到后,multiQuery就返回。返回的结果肯定是三个go func中最快返回的。(go func 中的queryFromSrc使用time.Sleep(random)来模拟不同请求延时)。显然,当第一个结果返回后,multiQuery函数就结束了,而其他两个go func还在等待返回。

如果我们使用不带缓冲区的channel,两个慢的goroutine将会卡在尝试去发送他们的结果到同一个channel,而这个channel将没有任何一个goroutine去读。因为multiQeury已经执行结束。这种情况叫做goroutine leak。与gc回自动回收的变量不同,泄漏的goroutine不会自动被回收。

所以编程中一定要注意,不使用的goroutine要让其正确地终止。

最后

以上就是等待母鸡为你收集整理的什么是goroutine leak?的全部内容,希望文章能够帮你解决什么是goroutine leak?所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(61)

评论列表共有 0 条评论

立即
投稿
返回
顶部