golang的Channel初始化的有缓存与无缓存解释
首先编程的时候遇到疑问,输出跟我所想预想不一样,后来查到了golang社区的帖子,其中一篇帖子 :健哥大人 做出了一些解释。
我摘抄重点过来:
无缓冲的与有缓冲channel有着重大差别,那就是一个是同步的 一个是非同步的。
比如
c1:=make(chan int) 无缓冲
c2:=make(chan int,1) 有缓冲
c1<-1
无缓冲: 不仅仅是向 c1 通道放 1,而是一直要等有别的携程 <-c1 接手了这个参数,那么c1<-1才会继续下去,要不然就一直阻塞着。
有缓冲: c2<-1 则不会阻塞,因为缓冲大小是1(其实是缓冲大小为0),只有当放第二个值的时候,第一个还没被人拿走,这时候才会阻塞。
我对以上做一些解释,首先确实得承认channel有缓存与无缓存确实差别巨大,缓存为1和不设置缓存输出有差别。但是上面有缓存的解释是合理的,无缓存的我保留一下意见,用用代码实例来做下分析。
首先看示例1:
package main import ( "fmt" ) func main() { jobs := make(chan int, 1) done := make(chan bool) go func() { // fmt.Println("GoStart") for i := 1; ; i++ { // fmt.Println("GoforSTART", i) j, more := <-jobs if more { fmt.Println("received job", j) } else { fmt.Println("received all jobs") done <- true return } // fmt.Println("GoforEND", i) } }() for j := 1; j <= 3; j++ { // fmt.Println("OutFOR", j) jobs <- j fmt.Println("sent job", j) } close(jobs) fmt.Println("sent all jobs") <-done }
其输出是:
sent job 1 received job 1 sent job 2 received job 2 sent job 3 sent all jobs received job 3 received all jobs
这是有缓存的情况,输出跟大家所预想的是一样的,每次遇到
jobs <- j
程序会继续向下执行,直到程序循环到下次 jobs <- j,因为jobs的开辟的缓存已满,故程序转而执行goroutine部分,在goroutine中,当程序执行至
j, more := <-jobs
取出channel中的值,等到goroutine中遇到阻塞,回到外部main()函数继续执行
然后分析看示例2:
将上一段得程序有缓存channel修改为无缓存,即:
jobs := make(chan int, 1)
修改为
jobs := make(chan int)
并将代码中的注释部分全部还原执行。
其输出是:
OutFOR 1 GoStart GoforSTART 1 received job 1 GoforEND 1 GoforSTART 2 sent job 1 OutFOR 2 sent job 2 OutFOR 3 received job 2 GoforEND 2 GoforSTART 3 received job 3 GoforEND 3 GoforSTART 4 sent job 3 sent all jobs received all jobs
我们分析:
当for循环运行至第一次 jobs <- j ,程序直接进入goroutine,由输出的“ GoStart” 紧跟 “OutFOR 1” 得到验证。然后程序执行至在goroutine中for的第二次循环
j, more := <-jobs
处阻塞,回到外部main()的for循环。
但外部main的for循环执行第二圈时,并未在 jobs <- j 后进入goroutine,而是继续执行,由
sent job 2 OutFOR 3
紧跟
OutFOR 2
得到验证。
而外部for进入第三次循环时阻塞,因为jobs中得值还未取出,故而转入goroutine继续执行。
问题出在
jobs <- j
是继续执行还是阻塞去在其他goroutine中传递值,按照本文开头索引的帖子所指出,应该jobs 通道放j,需要有携程接手这个参数,才可继续执行,但上面得分析看到情况并非如此。
示例3:
package mainimport ("fmt" )func main() {jobs := make(chan int)go func() {fmt.Println("Goroutin Start")for {select {case src := <-jobs:fmt.Println("Get ", src)}}}()for j := 0; j < 5; j++ {jobs <- jfmt.Println("Sent job ", j)}close(jobs)fmt.Println("finish.") }
其输出为:
Goroutin Start Get 0 Sent job 0 Sent job 1 Get 1 Get 2 Sent job 2 Sent job 3 Get 3 Get 4 Sent job 4 finish.
当遇到向channel写入值,是否往下执行是交替的,也就是说是随机的。
本文示例环境是go 1.4,本文所做的解释也是因为携程都是利用同一cpu在不同时间片上运行所做的输出分析。
goroutine利用阻塞同步携程之间的数据是非常重要的思想,但大家编程的时候要特别小心。
golang的Channel初始化的有缓存与无缓存解释相关推荐
- 全缓存、行缓存和无缓存
在标准I/O中,核心对象是流.所谓流,它是一个过程,所有的I/O操作都是简单的从程序的移进或移出,我们把这种字符流叫做流.标准I/O基于流的操作都是缓存文件系统. 缓存类型分为三种,分别是全缓存.行缓 ...
- 缓存(一)——浏览器缓存
浏览器缓存 一.概述 二.工作流程 三.缓存示例 四.几个控制缓存策略的响应头 强缓存 协商缓存 五.实例 一.概述 浏览器缓存即http缓存,将数据缓存在浏览器(即客户端). 服务端通过设置HTTP ...
- golang 中 channel 的详细使用、使用注意事项及死锁分析
什么是 channel 管道 它是一个数据管道,可以往里面写数据,从里面读数据. channel 是 goroutine 之间数据通信桥梁,而且是线程安全的. channel 遵循先进先出原则. 写入 ...
- golang中channel使用
1 golang中channel使用 文章目录 1 golang中channel使用 1.1 channel介绍 1.2 channel使用 1.2.1 channel声明和初始化 1.2.2 cha ...
- 深入了解golang 的channel
文章目录 1.channel 是什么 channel的特点 2.channel 的数据结构 hchan 等待队列和发送队列的类型包装 sudog 3.channel 分类 有缓冲channel 无缓冲 ...
- golang的channel实现原理
golang的channel实现原理 chan结构 src/runtime/chan.go type hchan struct {qcount uint // 当前队列中剩余元素个数dataqsiz ...
- GoLang之channel底层的数据结构是什么、channel的创建(2)
文章目录 GoLang之channel底层的数据结构是什么.channel的创建(2) 1.数据结构 2.创建 GoLang之channel底层的数据结构是什么.channel的创建(2) 1.数据结 ...
- golang中Channel通道(二)
golang中Channel通道(二) 一.带缓冲和不带缓冲的通道的区别 1.非缓冲通道 一次发送操作对应一次接收操作,对于一个goroutine来讲,它的一次发送,在另一个goroutine接收之前 ...
- GoLang之channel 在什么情况下会引起资源泄漏(10)
文章目录 GoLang之channel 在什么情况下会引起资源泄漏(10) GoLang之channel 在什么情况下会引起资源泄漏(10) Channel 可能会引发 goroutine 泄漏. 泄 ...
最新文章
- 衡阳之后,重估自动驾驶落地
- POJ1548最小路径覆盖
- 你一定不能错过的pandas 1.0.0四大新特性
- shiro学习(2):第一个shiro程序
- java变量命名规则_浅谈JAVA开发规范与开发细节(上)
- MYSQL 时间处理
- [bzoj 1398] Vijos1382寻找主人 Necklace 解题报告(最小表示法)
- pyqt:使用qrc文件配置图片资源,生成py文件
- NOIP模拟赛20191024 T1 嘟嘟噜【约瑟夫问题的mlogn解法】
- Virtuoso Layout 系列教程:01 软件安装教程 - 附资源包
- K8S(二)安装配置篇
- centOS最全下载地址
- Mac 格式化TF卡,获取原来的容量大小。
- uniapp 图片上传 删除
- 网易云音乐用户微观洞察精细化运营
- @Select注解动态sql语句
- 呵呵呵切克闹,Mysql优化来一套。
- vue入门(一)----工程vue_sell
- 教你win10电脑声音太小怎么办
- bizhubc226说明书_bizhubc226打印机如何扫描?