Go语言报错fatal error: all goroutines are asleep - deadlock!怎么解决?

今天小编给大家分享一下Go语言报错fatal error: all goroutines are asleep - deadlock!怎么解决的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

go 遍历通道与关闭通道

Go 通过 range 关键字来实现遍历读取到的数据,类似于与数组或切片。格式如下:

v, ok := <-ch

如果通道接收不到数据后 ok 就为 false,这时通道就可以使用 close() 函数来关闭。

代码示例:

package main

import (
        "fmt"
)

func fibonacci(n int, c chan int) {
        x, y := 0, 1
        for i := 0; i < n; i++ {
                c <- x
                x, y = y, x+y
        }
        close(c)
}

func main() {
        c := make(chan int, 10)
        go fibonacci(cap(c), c)
        // range 函数遍历每个从通道接收到的数据,因为 c 在发送完 10 个
        // 数据之后就关闭了通道,所以这里我们 range 函数在接收到 10 个数据
        // 之后就结束了。如果上面的 c 通道不关闭,那么 range 函数就不
        // 会结束,从而在接收第 11 个数据的时候就阻塞了。
        for i := range c {
                fmt.Println(i)
        }
}

/*********************************************************
输出结果
0
1
1
2
3
5
8
13
21
34
*********************************************************/

备注:如果不关闭通道,则报错:fatal error: all goroutines are asleep - deadlock!

错误代码示例:

package main

import (
  "fmt"
  "time"
)

func testDeadLock(c chan int){
  for{
    fmt.Println(<-c)
  }
}

func main() {
  c :=make(chan int)
  c<-3
  go testDeadLock(c)
  time.Sleep(time.Millisecond)
}

原因:首先我们这里通过make(chan int),开辟的通道是一种无缓冲通道,所以当对这个缓冲通道写的时候,会一直阻塞等到某个协程对这个缓冲通道读(大家发现没有这个与典型的生产者消费者有点不一样,当队列中“内容”已经满了,生产者再生往里放东西才会阻塞,而这里我讲c<-'A’理解为生产,他却是需要等到某个协程读了再能继续运行)。

main函数的执行在go语言中本身就是一个协程的执行,所以在执行到c<-'A’的时候,执行main函数的协程将被阻塞,换句话说main函数被阻塞了,此时不能在继续往下执行了,所以go testDeadLock©这个函数无法执行到了,就无法读到c中的内容了,所以整个程序阻塞,发生了死锁。

修改后代码示例:

package main

import (
  "fmt"
  "time"
)

func testDeadLock(c chan int){
  for{
    fmt.Println(<-c)
  }
}

func testInput(c chan int,n int) {
  c <- n
}
func main() {
  c :=make(chan int)
  go testInput(c,4)
  go testDeadLock(c)
  time.Sleep(time.Millisecond)
}

以上就是“Go语言报错fatal error: all goroutines are asleep - deadlock!怎么解决”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注***行业资讯频道。