Go 语言 channel 的阻塞问题Hello,大家好,又见面了!上一遍我们将 channel 相关基础以及使用场景 。这一篇,还需要再次进阶理解channel 阻塞问题 。以下创建一个chan类型为int , cap 为3 。
channel 内部其实是一个环形buf数据结构,是一种滑动窗口机制,当make完后,就分配在 Heap 上 。
上面 , 向 chan 发送一条“hello”数据go语言面试问题及答案:
如果 G1 发送数据超过指定cap时,会出现什么情况?
看下面实例:
以上会出现什么,chan 缓冲区允许大小为1,如果再往chan仍数据,满了就会被阻塞,那么是如何实现阻塞go语言面试问题及答案的呢?当 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之判断字符串中字符是否全都不同请实现 个算法 , 确定 个字符串go语言面试问题及答案的所有字符【是否全都不同】 。这 我们要求【不允
许使 额外的存储结构】 。给定 个string , 请返回 个bool值,true代表所有字符全都
不同,false代表存在相同的字符 。保证字符串中的字符为【ASCII字符】 。字符串的
度 于等于【3000】 。
这 有 个重点,第 个是 ASCII字符 , ASCII字符 字符 共有256个,其中128个是常
字符,可以在键盘上输。128之后的是键盘上 法找到的 。
然后是全部不同,也就是字符串中的字符没有重复的 , 再次,不准使 额外的储存结
构 , 且字符串 于等于3000 。
如果允许其他额外储存结构 , 这个题 很好做 。如果不允许的话,可以使 golang内置
的 式实现 。
通过 strings.Count 函数判断:
使 的是golang内置 法 strings.Count ,可以 来判断在 个字符串中包含
推荐阅读
- 开罗游戏开发物语最强主机,开罗游戏开发物语开罗怎么得
- 立方编程c语言,c语言求立方的代码
- Java霓虹灯源代码,霓虹灯源文件
- 希捷硬盘不识别怎么维修,希捷硬盘没反应
- 超级玛丽代码java 超级玛丽代码大全
- 关于佛山专注sap服务公司的信息
- 如何推广制剂室,新药推广策略
- 2020卡通冒险游戏下载,卡通人物冒险闯关游戏
- 缺少位置函数python python 缺省值