channel可以分为无缓冲和带缓冲的通道
无缓冲的,必须要一个协程发送,一个协程接收
package mainfunc main() { var ch = make(chan int) ch <- 1 <- ch}
在主协程main,执行到 ch <- 1,即发送完消息就阻塞了。
下一句 <- ch 永远无法执行,因为所有goroutines都睡着了(即没有协程接收) - 死锁!!!
假如是带缓冲的,如下
package mainfunc main() { var ch = make(chan int, 1) ch <- 1 <- ch}
则不会报错,因为main goroutine并没有被阻塞,带缓冲1
如果连续发两个,则会报错,如下:
package mainfunc main() { var ch = make(chan int, 1) ch <- 1 ch <- 1 <- ch}
但如果你及时接收了,则又不会报错,如下:
package mainfunc main() { var ch = make(chan int, 1) ch <- 1 <- ch ch <- 1 <- ch}
又或者在main goroutine里面再起一个goroutine,如下:
package mainfunc say(ch chan int) { ch <- 1}func main() { ch := make(chan int) go say(ch) // 新起协程,main goroutine并没有被阻塞 <- ch}