概述
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?所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复