在goroutine中添加select default语句时通道死锁

lawou6xi  于 2022-12-07  发布在  Go
关注(0)|答案(1)|浏览(133)

我正在学习信道,下面是我尝试的一个测试,但发生了死锁

func main() {
    ch := make(chan int)
    go func() {
        select {
        case ch <- 1:
            fmt.Println("send suc")
        default: // if comment this line, it will run smoothly
            fmt.Println("default")
        }
    }()
    time.Sleep(2) // do some time consuming thing...
    fmt.Printf("receive val: %d", <-ch)
}

我预料中没有出现僵局,但结果却是:

default
fatal error: all goroutines are asleep - deadlock!

但如果我去掉defaulttime.Sleep(2),代码就会顺利运行,结果:

send suc
receive val: 1

有人能解释为什么会出现死锁吗?

gab6jxml

gab6jxml1#

你有一个带有defaultselect,这意味着如果没有一个通信操作准备好,select将不会等待,不会阻塞,而是立即执行default。通道是无缓冲的,所以它的发送没有准备好(因为没有接收器准备好-main正在休眠)。
因此一旦main中的休眠结束,它就会尝试从通道接收,但此时没有人尝试在通道上发送。死锁。

相关问题