我尝试解决我的泄漏代码。但是向通道添加缓冲区并没有达到目的。我的代码package mainimport ( "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 中的泄漏函数,.. 泄漏。在这篇文章之后,我预计通过向通道添加缓冲区,可以避免泄漏。
1 回答
撒科打诨
TA贡献1934条经验 获得超2个赞
这里,在 Go Playground 中,是经过一些细微修改的原始代码:
延迟减少,除了
time.Sleep(5)
变为time.Sleep(time.Second)
;a
return
被删除,因为它变得不必要;a
fmt.Println
被注释掉,因为 thereturn
和未注释的fmt.Println
都会go vet
抱怨无法访问fmt.Println
;存储的通道
errChang
更改为无缓冲。
运行时,其输出为:
1 hola 2
(在 之前有一个小的延迟2
),表明您在 function 中启动的匿名 goroutine 确实leaking
仍在运行。
如果我们取消注释掉的注释fmt.Println
,则输出为:
1 hola 6 1
(在final之前有同样的轻微延迟1
)因为我们现在等待(然后打印)在return666
channel中计算并发送的值errChang
。
如果我们保留注释掉的注释fmt.Println
并使通道缓冲,则输出将变为:
1 hola 1
因为匿名 goroutine 现在能够将其值 (6) 推送到通道中。
通道本身以及存储在其中的单个值将被垃圾收集,因为此时没有对该通道的剩余引用。但请注意,仅仅使通道缓冲并不总是足够的。如果我们沿着通道发送两个值,程序将返回打印:
1 hola 2
因为匿名 goroutine 成功放入6
通道,但随后也阻止了尝试放入42
。
- 1 回答
- 0 关注
- 93 浏览
添加回答
举报
0/150
提交
取消