Go goroutine 泄漏

我尝试解决我的泄漏代码。但是向通道添加缓冲区并没有达到目的。

我的代码

package main


import (

    "fmt"

    "runtime"

    "time"

)


func main() {

    fmt.Println(runtime.NumGoroutine())

    leaking()

    time.Sleep(5)

    fmt.Println(runtime.NumGoroutine())

}


func leaking() {

    errChang := make(chan int, 1)

    go func() {

        xx :=  return666()

        errChang <- xx

    }()

    fmt.Println("hola")

    return


    fmt.Println(<-errChang)

}


func return666() int {

    time.Sleep(time.Second * 1)

    return 6

}

我最初的代码没有使用缓冲区,导致 go-routine 中的泄漏函数,.. 泄漏。在这篇文章之后,我预计通过向通道添加缓冲区,可以避免泄漏。


一只甜甜圈
浏览 94回答 1
1回答

撒科打诨

这里,在 Go Playground 中,是经过一些细微修改的原始代码:延迟减少,除了time.Sleep(5)变为time.Sleep(time.Second);areturn被删除,因为它变得不必要;afmt.Println被注释掉,因为 thereturn和未注释的fmt.Println都会go vet抱怨无法访问fmt.Println;存储的通道errChang更改为无缓冲。运行时,其输出为:1 hola 2(在 之前有一个小的延迟2),表明您在 function 中启动的匿名 goroutine 确实leaking仍在运行。如果我们取消注释掉的注释fmt.Println,则输出为:1 hola 6 1(在final之前有同样的轻微延迟1)因为我们现在等待(然后打印)在return666channel中计算并发送的值errChang。如果我们保留注释掉的注释fmt.Println并使通道缓冲,则输出将变为:1 hola 1因为匿名 goroutine 现在能够将其值 (6) 推送到通道中。通道本身以及存储在其中的单个值将被垃圾收集,因为此时没有对该通道的剩余引用。但请注意,仅仅使通道缓冲并不总是足够的。如果我们沿着通道发送两个值,程序将返回打印:1 hola 2因为匿名 goroutine 成功放入6通道,但随后也阻止了尝试放入42。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go