Golang的缓存chan和非缓存chan的区别
在使用golang的时候,可能都有这样的疑惑:带缓冲区但长度是1的channel和非缓冲channel有什么区别?比如下面的c1和c2
c1 := make(chan int, 1)
c2 := make(chan int)
以此,也可以扩充到,缓冲channel和非缓冲channel的区别,咱们还是先看看golang的官方文档的经典解释:
"If the channel is unbuffered, the sender blocks until the receiver has received the value.
If the channel has a buffer, the sender blocks only until the value has been copied to the buffer;
if the buffer is full, this means waiting until some receiver has retrieved a value."
似乎有点费解,咱们先看段程序之后再回过头来理解这句话,着急的可以直接跳到文章尾部看结论:-)
示例代码:
package main
import "fmt"
func main() {
bc := make(chan string, 1)
nbc := make(chan string)
bc <- "buffer-channel"
fmt.Println(<-bc)
//nbc <- "non-buffer-channel"
//fmt.Println(<-nbc)
var s string
go func() {
s = <-nbc
}()
nbc <- "non-buffer-channel"
fmt.Println(s)
}
有兴趣的可以跑一下上面的程序,包括试一下被注释掉的那两行。 简单来说, buffer channel,你只需要把数据copy到buffer里面你就可以返回(不阻塞), 除非你的数据超过了缓存区长度(有可能另一边取的不够快),导致无法写入才会阻塞 而对于non-buffer channel, 从上面注释掉的两行可以看看结果。 如果没有另外一个go rountine去取,你是写不进去的,所以开始就会阻塞,即:除非接受方收到/拿走数据,否则就会阻塞。
现在再去看开头的两句话,是不是更容易理解了?!