我在 Golang 教程中学习 Go select 语句时尝试对代码进行一些更改: https: //tour.golang.org/concurrency/5。但是,我遇到了问题:fatal error: all goroutines are asleep - deadlock!goroutine 1 [chan send]:main.main() concurrency.go:26 +0xa3goroutine 33 [chan receive]:main.main.func1(0xc000088000) concurrency.go:24 +0x42created by main.main concurrency.go:23 +0x89exit status 2这是我尝试并遇到问题的代码func fibonacci(c, quit chan int) { x, y := 0, 1 for { select { case c <- x: //sending value x into channel c x, y = y, x+y case <-quit: //receive value from quit fmt.Println("quit") return } }}func main() { //create two channels c := make(chan int) quit := make(chan int) go func() { //spin off the second function in order to let consume from c , so fibonaci can continue to work fmt.Println(<-c) //read value from channel c }() //Try moving the statement that send value to channel quit in order to //return function fibonacci quit <- 0 fibonacci(c, quit)}起初,我认为结果将与下面代码的结果相同//function fibonacci is same with the first onefunc fibonacci(c, quit chan int) { x, y := 0, 1 for { select { case c <- x: //sending value x into channel c x, y = y, x+y case <-quit: //receive value from quit fmt.Println("quit") return } }}func main() { //create two channels c := make(chan int) quit := make(chan int) go func() { //spin off the second function in order to let consume from c , so fibonaci can continue to work fmt.Println(<-c) //read value from channel c quit <- 0 //CHANGE: move the statement inside the closure function }() fibonacci(c, quit)}输出是0quit您能解释一下执行第一个示例时死锁的根本原因是什么吗?在go例程中发送值退出通道与在主线程中发送值退出通道有什么区别?感谢你们。
1 回答
宝慕林4294392
TA贡献2021条经验 获得超8个赞
该quit通道是无缓冲通道。在发送和接收 goroutine 都准备好之前,无缓冲通道上的通信不会继续。该语句quit <- 0在应用程序执行函数以接收值之前阻塞。接收 Goroutine 永远不会准备好
通过关闭通道修复:
c := make(chan int)
quit := make(chan int)
go func() {
fmt.Println(<-c)
}()
close(quit)
fibonacci(c, quit)
...或者通过缓冲通道
c := make(chan int, 1) // <- note size 1
quit := make(chan int)
go func() {
fmt.Println(<-c)
}()
quit <- 0
fibonacci(c, quit)
在这种情况下,fibonacci将在产生值之前退出。
- 1 回答
- 0 关注
- 103 浏览
添加回答
举报
0/150
提交
取消