Go 语言 channel 的阻塞问题Hello,大家好 , 又见面了!上一遍我们将 channel 相关基础以及使用场景 。这一篇,还需要再次进阶理解channel 阻塞问题 。以下创建一个chan类型为int,cap 为3 。
channel 内部其实是一个环形buf数据结构,是一种滑动窗口机制,当make完后,就分配在 Heap 上 。
上面,向 chan 发送一条“hello”数据:
如果 G1 发送数据超过指定cap时,会出现什么情况?
看下面实例:
以上会出现什么,chan 缓冲区允许大小为1,如果再往chan仍数据,满了就会被阻塞,那么是如何实现阻塞的呢?当 chan 满时 , 会进入 gopark,此时 G1 进入一个 waiting 状态,然后会创建一个 sudog 对象,其实就sendq队列,把 200放进去 。等 buf 不满的时候 , 再唤醒放入buf里面 。
通过如下源码,你会更加清晰:
上面,从 chan 获取数据:
Go 语言核心思想:“Do not communicate by sharing memory; instead, share memory by communicating.” 你可以看看这本书名叫:Effective Go
如果接收者,接收一个空对象 , 也会发生什么情况?
代码示例:
也会报错如下:
上面,从 chan 取出数据,可是没有数据了 。此时,它会把 接收者 G2 阻塞掉,也是和G1发送者一样,也会执行 gopark 将状态改为 waiting,不一样的点就是 。
正常情况下,接收者G2作为取出数据是去 buf 读取数据的 , 但现在,buf 为空了,此时,接收者G2会将sudog导出来,因为现在G2已经被阻塞了嘛 , 会把G2给G,然后将t := -ch中变量t是在栈上的地址,放进去elem,也就是说,只存它的地址指针在sudog里面 。
最后,ch - 200当G1往 chan 添加200这个数据,正常情况是将数据添加到buf里面 , 然后唤醒 G2 是吧,而现在是将 G1 的添加200数据直接干到刚才G2阻塞的t这里变量里面 。
你会认为 , 这样真的可以吗?想一想,G2 本来就是已经阻塞了,然后我们直接这么干肯定没有什么毛?。倚侍岣吡耍?不需要再次放入buf再取出,这个过程也是需要时间 。不然,不得往chan添加数据需要加锁、拷贝、解锁一序列操作 , 那肯定就慢了,我想Go语言是为了高效及内存使用率的考虑这样设计的 。(注意,一般都是在runtime里面完成,不然会出现象安全问题 。)
总结:
chan 类型的特点:chan 如果为空,receiver 接收数据的时候就会阻塞等待,直到 chan 被关闭或者有新的数据到来 。有这种个机制,就可以实现 wait/notify 的设计模式 。
相关面试题:
golang面试题2之判断字符串中字符是否全都不同请实现 个算法,确定 个字符串的所有字符【是否全都不同】 。这 我们要求【不允
许使 额外的存储结构】 。给定 个string , 请返回 个bool值,true代表所有字符全都
不同 , false代表存在相同的字符 。保证字符串中的字符为【ASCII字符】 。字符串的
度 于等于【3000】 。
这 有 个重点,第 个是 ASCII字符 , ASCII字符 字符 共有256个,其中128个是常
字符,可以在键盘上输。128之后的是键盘上 法找到的 。
然后是全部不同,也就是字符串中的字符没有重复的,再次,不准使 额外的储存结
构,且字符串 于等于3000 。
如果允许其他额外储存结构,这个题 很好做 。如果不允许的话,可以使 golang内置
的 式实现 。
通过 strings.Count 函数判断:
使 的是golang内置 法 strings.Count ,可以 来判断在 个字符串中包含
的另外 个字符串的数量
还有不同的方法同样可以实现,你了解吗?
推荐go相关技术 专栏
gRPC-go源码剖析与实战_带你走进gRPC-go的源码世界-CSDN博客
面试问题总结(一)Golang 使用go语言的好处: go语言的设计是务实的, go在针对并发上进行了优化, 并且支持大规模高并发, 又由于单一的码格式, 相比于其他语言更具有可读性, 在垃圾回收上比java和Python更有效, 因为他是和程序同时执行的.
1. 进程, 线程, 协程的区别, 协程的优势
2. 讲一下GMP模型(重点)
3. Go的GC, 混合写屏障(重点)
4. go的Slice和数组的区别, slice的扩容原理(重点)
5. 讲一下channel,实现原理(重点)
6. 讲一下Go的Map的实现原理, 是否线程安全, 如何实现安全(重点)
7. new 和 make 的区别
8. 说一下内存逃逸
9. 函数传指针和传值有什么区别
10. goroutine之间的通信方式
11. 测试是怎么做的(单元测试, 压力测试)
12. 堆和栈的区别
【go语言面试卷 go语言编程题】go语言面试卷的介绍就聊到这里吧 , 感谢你花时间阅读本站内容,更多关于go语言编程题、go语言面试卷的信息别忘了在本站进行查找喔 。
推荐阅读
- 电商平台如何防治假货违规,如何解决电商平台的假货问题
- 幼儿园大带小体育游戏,幼儿大型体育游戏
- 直播卡脸视频教程下载,直播卡是什么东西
- php查询数据库一个数据 php数据库查询结果处理
- asp.netsql换行符,sql语句换行符
- 夜景拍摄前准备什么,夜景拍摄需要注意什么
- go语言工资看准网 go语言工作岗位
- 微信连wifi先关注公众号,关注微信连接wifi
- 电视添加爱奇艺怎么添加,怎么在电视上添加爱奇艺