英文:
Deadlock between goroutines
问题
我是你的中文翻译助手,以下是翻译好的内容:
我对Go语言还不熟悉。当我注释掉第二个goroutine时,会出现致命错误。我不明白是什么原因导致了这个错误的发生。你能解释一下吗?
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
go func() {
for i := 0; i < 10; i++ {
ch <- i
}
} ()
// go func() {
for {
if num, ok := <-ch; !ok {
break
} else {
fmt.Printf("%d\n", num)
}
}
// } ()
time.Sleep(2 * time.Second)
close(ch)
}
这段代码输出以下内容:
0
1
2
3
4
5
6
7
8
9
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
/tmp/sandbox169127128/main.go:17 +0xa0
程序已退出。
希望对你有帮助!
英文:
I'm new to Go. When I comment out the second goroutine, there is a fatal error. I don't understand what causes this error to occur. Can you explain it to me?
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
go func() {
for i := 0; i < 10; i++ {
ch <- i
}
} ()
// go func() {
for {
if num, ok := <-ch; !ok {
break
} else {
fmt.Printf("%d\n", num)
}
}
// } ()
time.Sleep(2 * time.Second)
close(ch)
}
This prints the following code:
0
1
2
3
4
5
6
7
8
9
fatal error: all goroutines are asleep - deadlock!
goroutine 1 [chan receive]:
main.main()
/tmp/sandbox169127128/main.go:17 +0xa0
Program exited.
答案1
得分: 5
接收循环在从发送goroutine接收到所有值后,阻塞在从ch
接收上。运行时检测到程序被阻塞并引发恐慌。
修复方法是在发送完所有值后关闭通道:
go func() {
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
} ()
在关闭的通道上接收会产生值0, false
。接收循环在接收到false值时中断。
从程序末尾删除close(ch)
。
英文:
The receiving for loop blocks on receive from ch
after receiving all values from the sending goroutine. The runtime detects that the program is stuck and panics.
The fix is to close the channel after sending all values:
go func() {
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
} ()
Receive on the closed channel yields the value 0, false
. The receiving for loop breaks on the false value.
Remove close(ch)
from the end of the program.
答案2
得分: 2
因为在第一个goroutine退出之前没有关闭通道。下面的代码应该可以工作。
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
go func() {
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
} ()
//go func() {
for {
if num, ok := <-ch; !ok {
break
} else {
fmt.Printf("%d\n", num)
}
}
//} ()
time.Sleep(2 * time.Second)
}
在这里尝试一下:https://play.golang.org/p/OdxNqbaZmj
英文:
Because you're not closing the channel before the first goroutine exits. The below code should work.
package main
import (
"fmt"
"time"
)
func main() {
ch := make(chan int)
go func() {
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
} ()
//go func() {
for {
if num, ok := <-ch; !ok {
break
} else {
fmt.Printf("%d\n", num)
}
}
//} ()
time.Sleep(2 * time.Second)
}
Try it out here: https://play.golang.org/p/OdxNqbaZmj
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论