读取 go channel 为什么直接死锁?

开始学习 go channel 的姿势, 为什么下面这段代码运行时直接报死锁错误.

// main.go
package main

func main() {
    ch := make(chan int)
    defer close(ch)
    <-ch
}

报错信息如下:

fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan receive]:
main.main()
    E:/projects/godemo1/main.go:7 +0x8d

没看明白为什么直接报错?

觉得还不错点个赞呗!
taadis
最佳答案

file

我个人的理解是:不论是 有缓冲通道还是无缓冲通道,通道中任意一方永久性阻塞,就会引发死锁错误。

file

4年前 评论
taadis (楼主) 4年前
root01 (作者) 4年前
taadis (楼主) 4年前
讨论数量: 5

Golang自带死锁检测机制,当发现当前协程再也没有机会被唤醒时,则会panic

4年前 评论
taadis (楼主) 4年前

这是个无缓冲的通道,发送和接收要求同时进行,不能再主协程这么操作。

4年前 评论

all goroutines are asleep 都在睡觉呢

4年前 评论
pardon110

代码中的主协程(main函数)存在的无缓冲通道有收无发,好比打枪没上子弹,射击自然无法成功。 你可以这样

package main

import (
    "fmt"
)

func main() {
    ch := make(chan int)
    go func() {
        ch <- 3
    }()
    defer close(ch)
    <-ch
    fmt.Print("over")
}

或者用缓冲通道,这样

package main

import (
    "fmt"
)

func main() {
    ch := make(chan int, 1)
    ch <- 3 
    defer close(ch)
    <-ch
    fmt.Print("over")
}

简而言之,对于通道读写大多数情况下需要进出成双成对,缺少任何一方皆产生死锁。

4年前 评论

file

我个人的理解是:不论是 有缓冲通道还是无缓冲通道,通道中任意一方永久性阻塞,就会引发死锁错误。

file

4年前 评论
taadis (楼主) 4年前
root01 (作者) 4年前
taadis (楼主) 4年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!