声明chan时,设置大小的区别。

ch := make(chan int, 1)
    for {
        select {
        case ch <- 0:
        case ch <- 1:
        }
        i := <-ch
        fmt.Println("Value received:", i) // 随机输出0和1
    }
ch := make(chan int)
    for {
        select {
        case ch <- 0:
        case ch <- 1:
        }
        i := <-ch
        fmt.Println("Value received:", i) // 报错:fatal error: all goroutines are asleep - deadlock!
    }

有没有大神可以解释下为什么啊?

阅读 9.3k
2 个回答

不带缓冲的channel写完就阻塞,这种情况只有其他协程中有对应的读才能解除阻塞。而带缓冲的channel要直到写满+1才阻塞。所以根据你写的代码,make(chan int, 1),刚好一写一读,假如你多写一次其实也会阻塞。而make(chan int)写了就阻塞了,根本没机会读。可以对比下面的代码

ch := make(chan int, 1)
    for {
        select {
        case ch <- 0:
        case ch <- 1:
        }
        ch <- 2
        i := <-ch
        fmt.Println("Value received:", i) // 随机输出0和1
    }

    ch := make(chan int)
    for {
        go func() {
            i := <-ch
            fmt.Println("Value received:", i) // 报错:fatal error: all goroutines are asleep - deadlock!
        }()
        select {
        case ch <- 0:
        case ch <- 1:
        }
    }
新手上路,请多包涵

不带缓冲的channel写完就阻塞

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题