gpt4 book ai didi

Go goroutine 泄漏

转载 作者:行者123 更新时间:2023-12-01 22:17:34 28 4
gpt4 key购买 nike

在这篇关于 go-routines 泄漏的帖子之后,https://www.ardanlabs.com/blog/2018/11/goroutine-leaks-the-forgotten-sender.html ,我试图解决我的泄漏代码。但是向 channel 添加缓冲区并没有起到作用。

我的代码

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,.. 泄漏。在帖子之后,我希望通过向 channel 添加缓冲区,它可以避免泄漏。

最佳答案

Here, in the Go Playground , 是您的原始代码,稍作修改:

  • 延迟减少,time.Sleep(5) 除外变成 time.Sleep(time.Second) ;
  • 一个 return被删除,因为它变得不必要;
  • 一个 fmt.Println被注释掉,因为 return和未注释的 fmt.Println , go vet提示无法访问 fmt.Println ;
  • 存储在 errChang 中的 channel 更改为无缓冲。

  • 运行时,其输出为:
    1
    hola
    2

    (在 2 之前有一点延迟),这表明您确实在函数 leaking 中启动了匿名 goroutine仍在运行。

    如果我们 uncomment the commented-out fmt.Println ,输出为:
    1
    hola
    6
    1

    (在最终 1 之前有相同的轻微延迟)因为我们现在等待(然后打印)在 return666 中计算的值并通过 channel errChang 发送.

    如果我们 keep the commented-out fmt.Println commented out and make the channel buffered ,输出变为:
    1
    hola
    1

    因为匿名 goroutine 现在能够将其值 (6) 推送到 channel 中。

    channel 本身以及存储在其中的单个值将被垃圾收集,因为此时没有对 channel 的剩余引用。但是请注意,简单地使 channel 缓冲并不总是足够的。如果我们 send two values down the channel ,程序返回打印:
    1
    hola
    2

    因为匿名 goroutine 成功地把 6进入 channel ,但随后阻止尝试放入 42在以及。

    关于Go goroutine 泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58597199/

    28 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com