我的功能创建一个没有缓冲区的通道。此功能继续创建其他几个并发的匿名函数,写作上述频道。然后,函数继续等待通道上的输入,然后返回值。
请参见下面的示例
package main
import (
"time"
"fmt"
"strconv"
"math/rand"
)
func main() {
for{
text := foo()
fmt.Println(text)
time.Sleep(time.Second)
}
}
func foo() string {
ch := make(chan string)
for i := 0; i < 10; i++ {
// Create some threads
go func(i int) {
time.Sleep(time.Duration(rand.Intn(1000))*time.Millisecond)
ch <- strconv.Itoa(i)
}(i)
}
return <- ch
}
即使整个函数(示例(为"死"?
,仍在频道上等待的匿名函数会发生什么?他们会被收集为垃圾,还是他们会永远徘徊在我的计算机记忆中(或直到我杀死主线程(,以拼命的尝试在传递之前发送他们的最后一条消息?
您有一个goroutine泄漏。
package main
import (
"fmt"
"math/rand"
"runtime"
"strconv"
"time"
)
func main() {
for {
text := foo()
fmt.Println(text, "NumGoroutine", runtime.NumGoroutine())
time.Sleep(time.Second)
}
}
func foo() string {
ch := make(chan string)
for i := 0; i < 10; i++ {
// Create some threads
go func(i int) {
time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
ch <- strconv.Itoa(i)
}(i)
}
return <-ch
}
输出:
$ go run leak.go
4 NumGoroutine 10
4 NumGoroutine 20
0 NumGoroutine 28
8 NumGoroutine 37
2 NumGoroutine 46
8 NumGoroutine 55
2 NumGoroutine 64
3 NumGoroutine 73
8 NumGoroutine 82
1 NumGoroutine 91
4 NumGoroutine 100
<<--SNIP-->>
4 NumGoroutine 4006
7 NumGoroutine 4015
6 NumGoroutine 4024
9 NumGoroutine 4033
9 NumGoroutine 4042
9 NumGoroutine 4051
1 NumGoroutine 4060
0 NumGoroutine 4069
4 NumGoroutine 4078
0 NumGoroutine 4087
6 NumGoroutine 4096
^Csignal: interrupt
$
就像记忆泄漏一样,goroutine泄漏不好。
有关某些背景,请参阅GO:建议:运行时:垃圾收集Goroutines被封锁了#19702:封闭。