首页 > 解决方案 > golang为什么不能在主线程上将值传递给通道

问题描述

情况1

package main

func main()  {
    dogChan := make(chan int)
    dogChan <- 1
}
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
    /Users/xuzhongwei/Source/awesomeProject/main.go:5 +0x50

案例2

package main

func main()  {
    dogChan := make(chan int)

    go func(ch chan int) {
        
    }(dogChan)
    dogChan <- 1
}
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
    /Users/xuzhongwei/Source/awesomeProject/main.go:9 +0x72

案例3

package main

func main()  {
    dogChan := make(chan int)

    go func(ch chan int) {
        <- ch
    }(dogChan)
    dogChan <- 1
}

案例4

package main

func main()  {
    dogChan := make(chan int)
    
    go func(ch chan int) {
        <- ch
    }(dogChan)
    dogChan <- 1
    dogChan <- 2
}
fatal error: all goroutines are asleep - deadlock!

goroutine 1 [chan send]:
main.main()
    /Users/xuzhongwei/Source/awesomeProject/main.go:10 +0x90

案例5

package main

func main()  {
    dogChan := make(chan int)

    go func(ch chan int) {
        for {
            select {
                case <- ch:
            }
        }

    }(dogChan)
    dogChan <- 1
    dogChan <- 2
    dogChan <- 3
    dogChan <- 4
    dogChan <- 5
}

谁能告诉我为什么 case1、case2 出错而 case3 没问题?在 case1 中,我的猜测是 goroutine 中没有使用 dogChan,因此它被视为关闭。在case2中,我的猜测是虽然dogChan在goroutine中传递但它没有在goroutine中使用,所以它被视为关闭

谁能告诉我为什么 case4 出错而 case5 正常?

标签: gogoroutine

解决方案


为什么你认为那发生在case1and case2?通道旨在充当发送方和接收方之间的同步原语。您有一个发件人在频道上发送,dogChan但没有人在其上接收。如果没有接收 goroutine 或 goroutine 上的接收操作,发送者只会阻塞(作为无缓冲通道)

同样的问题case4,您在通道上有两个发送,但在 goroutine 上有一个接收。将dogChan <- 2永远阻塞。在case5中,如果您的意图是从通道中读取,只需使用range循环来迭代通过它发送的连续值。


推荐阅读