Go语言带缓冲的通道
参考:
http://c.biancheng.net/view/100.html
关键点
通过关键词汇
,实现快速
理解,记忆
的目的
:
1、
缓存
通道和无缓存
通道的主要
区别?
无
缓存通道,要求数据
的发送
和接收
必须同时
完成
有
缓存通道,数据的发送
和接收不是
必须同时
完成的2、
缓存
通道 存在阻塞
情况不
?通道
被填满
时,如果发送
数据,协程会
阻塞,也就是协程等待着
通道里
没有数据
时,还
一直接收
数据,协程也会
阻塞,协程
开始等待
3、为什么Go语言对
通道
要限制
长度而不
提供无限长度
的通道?防止
数据发
送方一直
发送数据,内存
不断增加
,可能导致
应用程序奔溃
1、创建带缓冲
通道
如何创建
带缓冲的通道
呢? 参见如下代码:
通道实例 := make(chan 通道类型, 缓冲大小)
-
通道类型:和无缓冲通道用法一致,影响通道发送和接收的数据类型。
-
缓冲大小:决定通道最多可以保存的元素数量。
-
通道实例:被创建出的通道实例。
下面通过一个例子中来理解带缓冲通道的用法,参见下面的代码:
package main
import "fmt"
func main() {
// 创建一个3个元素缓冲大小的整型通道
ch := make(chan int, 3)
// 查看当前通道的大小
fmt.Println(len(ch))
// 发送3个整型元素到通道
ch <- 1
ch <- 2
ch <- 3
// 查看当前通道的大小
fmt.Println(len(ch))
}
代码输出如下:
0
3
代码说明如下:
-
第 8 行,创建一个带有 3 个元素缓冲大小的整型类型的通道。
-
第 11 行,查看当前通道的大小。带缓冲的通道在创建完成时,内部的元素是空的,因此使用 len() 获取到的返回值为 0。
-
第 14~16 行,发送 3 个整型元素到通道。因为使用了缓冲通道。即便没有 goroutine 接收,发送者也不会发生阻塞。
-
第 19 行,由于填充了 3 个通道,此时的通道长度变为 3。
2、阻塞
条件
带
缓冲通道在很多特性上和无缓冲
通道是类似的。
无
缓冲通道可以看作是长度永远为 0
的带缓冲
通道。
因此根据这个特性,带
缓冲通道在下面列举的情况下依然会发生阻塞
:
-
带缓冲通道
被填满
时,尝试再次
发送数据时发生阻塞
。 -
带缓冲通道
为空
时,尝试接收
数据时发生阻塞
。
2.1、为什么Go语言对通道要限制长度
而不
提供无限长度
的通道?
我们知道通道(channel)
是在两
个 goroutine
间通信的桥梁
。
使用 goroutine 的代码必然有一方提供
数据,一方消费
数据。
当提供
数据一方的数据供给速度大于
消费方的数据处理速度时,
如果通道不限制
长度,那么内存
将不断膨胀直到应用崩溃
。
因此,限制通道的长度有利于约束数据提供方的供给速度,
供给数据量必须在消费方处理量+通道长度的范围内,
才能正常地处理数据。