作者:ReganYueGolang协程之了解管道的缓存能力 大家好,这里是努力变得优秀的R君,这次我们继续来进行Golang系列《让我们一起Golang》,区块链系列内容明年会继续更新,共识算法已经基本完毕,如果不出意外,元旦那个星期就是介绍如何构建公链项目了,本次我们来了解管道的缓存能力,这是一个比较容易理解的知识点,我们来看一看吧!
来源:恒生LIGHT云社区
我们之前讲过,当使用make建立管道时,第二个参数为零,就证明这个管道是无缓存能力的管道。只要没人写就永远读不出来,只要没人读就永远写不进去。例如:
ch := make(chan int,0)
管道的缓冲区能被初始化为指定的缓冲区容量。 如果为零,或者省略了大小,则该通道是无缓冲的。
如果将第二个参数改为8(这里可以为任意大小),这就说明缓存能力为8,即使不读,也能写入8个元素。
package mainimport (
"fmt"
"time"
)func main() {
//The channel's buffer is initialized with the specified buffer capacity.
//If zero, or the size is omitted, the channel is unbuffered.
ch := make(chan int,0)go func() {
ch <- 123
fmt.Println("数据已写入")
}()go func() {
time.Sleep(2*time.Second)
x:= <- ch
fmt.Println("数据已读出",x)
}()time.Sleep(5*time.Second)
fmt.Println("Game Over!")
}
这段代码在运行过程中,由于一条协程在写入管道缓冲区,另一条协程在读取管道的缓冲区,但是读取管道缓冲区的那条协程会sleep 两秒,所以在前两秒另一条写入管道缓冲区的协程也不能写入。
如果让写入管道缓冲区的那条协程sleep两秒,那么前两秒另一条读取管道缓冲区的协程也不能读取数据。
如果一个缓冲区大小为3的管道,写入4个值,那么第4个值就写入不了,运行结果是这样的:
写入1
写入2
写入3
下面我们来看一看管道内的元素个数及它的缓存能力吧:
package mainimport (
"fmt"
"time"
)func main101() {
ch := make(chan int,3)go func() {
ch <- 1
fmt.Println("写入1")
ch <- 2
fmt.Println("写入2")
ch <- 3
fmt.Println("写入3")
//管道的缓冲区已经存满,不能再写入!
ch <- 4
fmt.Println("写入4")
}()
time.Sleep(5 * time.Second)
}func main() {
ch := make(chan int,3)
fmt.Println("元素的个数为",len(ch),"缓存能力为",cap(ch));
ch <- 123
fmt.Println("元素的个数为",len(ch),"缓存能力为",cap(ch));
ch <- 123
fmt.Println("元素的个数为",len(ch),"缓存能力为",cap(ch));
ch <- 123
fmt.Println("元素的个数为",len(ch),"缓存能力为",cap(ch));
}
运行结果是
元素的个数为 0 缓存能力为 3
元素的个数为 1 缓存能力为 3
元素的个数为 2 缓存能力为 3
元素的个数为 3 缓存能力为 3
fatal error: all goroutines are asleep - deadlock!goroutine 1 [chan send]:
main.main()
E:/main.go:36 +0x4e5Process finished with exit code 2
我们可以看到管道的缓存能力是没有变化的,但是存入的元素个数是在变化的。
我们可以看到这里出现了死锁,这里主协程永远无法继续执行。
我们再来了解一下管道的有关知识。
据了解,管道是建立在堆上面的。使用make函数返回的是指针,这就是为什么我们能够在函数之间传递管道,不需要传递指向管道的指针。
ch := make(chan int,0)
使用make创建一个管道只能传输同一类型的数据,建立一个管道时需要指定一个数据类型,不允许通过一个管道传输多种类型的数据。
想向技术大佬们多多取经?开发中遇到的问题何处探讨?如何获取金融科技海量资源?
恒生LIGHT云社区,由恒生电子搭建的金融科技专业社区平台,分享实用技术干货、资源数据、金融科技行业趋势,拥抱所有金融开发者。
扫描下方小程序二维码,加入我们!
【Golang协程之了解管道的缓存能力】
文章图片
推荐阅读
- 【golang】leetcode中级-字母异位词分组&无重复字符的最长子串
- 彻底理解Golang Map
- kratos线上开源年会它来啦~
- 深入浅出 Golang 资源嵌入方案(go-bindata篇)
- 深入浅出 Golang 资源嵌入方案(前篇)
- golang 经典案例总结
- Go实战 | 基于有向无环图的并发执行流的实现
- Golang 数组和切片
- Go JSON编码与解码()
- golang map基础知识