英文:
Why am I getting a memory leak?
问题
我有以下代码:http://play.golang.org/p/1aaive8KQx
当我打印runtime.NumGoroutine()时,我得到3。我不应该只得到1吗?为什么?
package main
import (
"log"
"runtime"
"time"
)
func main() {
for i := 1; i <= 10; i++ {
ch := make(chan int, 10)
timeout := time.Tick(1 * time.Second)
for i := 1; i <= 10; i++ {
go func(i int) {
time.Sleep(2 * time.Second)
ch <- i
}(i)
}
for i := 1; i <= 10; i++ {
select {
case j := <-ch:
log.Println(j)
case <-timeout:
log.Println("timeout")
}
}
log.Println("Processes", runtime.NumGoroutine())
}
}
英文:
I have the following: http://play.golang.org/p/1aaive8KQx
When I print the runtime.NumGoroutine() I get 3. Shouldn't I be getting just 1? Why?
package main
import (
"log"
"runtime"
"time"
)
func main() {
for i := 1; i <= 10; i++ {
ch := make(chan int, 10)
timeout := time.Tick(1 * time.Second)
for i := 1; i <= 10; i++ {
go func(i int) {
time.Sleep(2 * time.Second)
ch <- i
}(i)
}
for i := 1; i <= 10; i++ {
select {
case j := <-ch:
log.Println(j)
case <-timeout:
log.Println("timeout")
}
}
log.Println("Processes", runtime.NumGoroutine())
}
}
答案1
得分: 1
有一个奇怪的竞态条件。基本上,当你调用Println
时,一些goroutine仍在运行,但很快就会终止。在Println
之前放一个睡眠,你会得到1个进程
。如果你读取日志,你会看到2个超时 - 这意味着你在循环中跳过了2次通道读取。不知何故,它给了你的主goroutine时间从通道中读取8个值并在2个goroutine终止之前调用Println
。这是一个竞态条件,所以很难准确描述发生了什么。除了你的代码之外,调度器和通道的实现也在这里起着重要作用。
英文:
There is a weird race condition. Basically what happens is when you call Println
some goroutines are still running but will terminate shortly. Put a sleep before Println
and you will get 1 Processes
. If you read the log you will see 2 timeouts - it means you skipped 2 channel reads in the loop. Somehow it gives your main goroutine time to read 8 values from the channel and call Println
before 2 goroutines are terminated. It's a race condition so it's hard to describe exactly what's going on. Apart from your code the scheduler and channels implementation also play major here.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论