为什么在使用select并将值依次馈入2个通道时,所有goroutine都处于睡眠状态?

问题描述

我有2个通道,它们在main函数的开始处将值传递给它,然后我有一个匿名goroutine应当打印值:

package main

import (
    "fmt"
)

func main() {
    rand1 := make(chan int)
    rand2 := make(chan int)
    rand1 <- 5
    rand2 <- 7

    go func() {
        select {
        case <-rand1:
            fmt.Println("rand1")
        case <-rand2:
            fmt.Println("rand2")
            return
        }
        fmt.Println("test")
    }()
}

但是我收到错误Fatal error: all goroutines are asleep - deadlock!。但是应该在rand2通道收到其值时返回匿名goroutine。

解决方法

对通道的写入将被阻止,直到从另一个goroutine读取该通道为止。在启动阅读器goroutine之前,您的程序正在尝试写入通道。首先启动阅读器goroutine,然后写入通道。

并非以编写方式,goroutine只会从其中一个通道读取并返回,因此您的程序将再次死锁,因为第二次写入将被阻塞。