goroutines之间的死锁
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
Program exited.
在从发送 goroutine 接收到所有值后,接收 for 循环会阻塞从 ch
接收。 runtime检测到程序卡死panic
解决方法是在发送所有值后关闭通道:
go func() {
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
} ()
在关闭的通道上接收产生值 0, false
。接收 for 循环在 false 值处中断。
从程序末尾删除 close(ch)
。
因为您没有在第一个 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)
}
我是 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
Program exited.
在从发送 goroutine 接收到所有值后,接收 for 循环会阻塞从 ch
接收。 runtime检测到程序卡死panic
解决方法是在发送所有值后关闭通道:
go func() {
for i := 0; i < 10; i++ {
ch <- i
}
close(ch)
} ()
在关闭的通道上接收产生值 0, false
。接收 for 循环在 false 值处中断。
从程序末尾删除 close(ch)
。
因为您没有在第一个 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)
}