Go chan的底层原理

什么是channel?

chan是Go中的一种特殊类型,不同的协程可以通过channel来进行数据交互。

channel分为有缓冲区与无缓冲区两种。

无缓冲区chan

如果当前协程向无缓冲区chan发送一条消息,但是这个chan没有就绪的接收协程时,当前协程就会被阻塞,直到出现一个接收者协程就绪,并从chan中接收这条消息。

有缓冲区chan

在缓冲区被填满后,尝试向chan发送消息的协程将会被阻塞。当缓冲区内消息数量为0时,尝试从chan中读取消息的协程将被阻塞。

channel的底层实现

channel是基于环形队列实现的。

type hchan struct {qcount uint          // 当前队列中剩余元素个数dataqsiz uint        // 环形队列长度(可以存放的元素个数)buf unsafe.Pointer   // 环形队列指针elemsize uint16      // 每个元素的⼤⼩closed uint32        // 标识关闭状态elemtype *_type      // 元素类型sendx uint           // 队列下标,指示元素写入时存放到队列中的位置 xrecvx uint           // 队列下标,指示元素从队列的该位置读出  recvq waitq          // 等待读消息的协程队列sendq waitq          // 等待写消息的协程队列lock mutex           // 互斥锁,chan不允许并发读写
}
环形队列(buf)

由buf指针指向环形队列,所有进入到chan的数据都将会存入环形队列中。

等待队列(recvq / sendq)
  • 读消息的协程等待队列(recvq):
    如果该chan缓冲区为空,或者该chan没有缓冲区,那么当前的读消息协程将被阻塞。被阻塞的读消息协程会变放入读消息的协程等待队列。

  • 写消息的协程等待队列(sendq):
    如果该chan缓冲区已满,或者该chan没有缓冲区,那么当前的写消息协程将被阻塞。被阻塞的写消息协程会变放入写消息的协程等待队列。

写数据流程

图片来源:https://www.jianshu.com/p/359a6e1ccd94

读数据流程

图片来源:https://www.jianshu.com/p/359a6e1ccd94

唤醒协程
  • 因读阻塞的协程会被向chan写数据的协程唤醒。

  • 因写阻塞的协程会被从chan读数据的协程唤醒。

一般情况下recvq和sendq至少有一个队列为空。只有一个例外,那就是同一个协程使用select语句向chan一边写数据一边读数据。

channel在什么情况下会Panic?

  • 向已经关闭的chan写入数据会发生Panic
  • 再次关闭已经关闭的chan会发生Panic
  • 关闭一个值为nil的chan会发生Panic

文章参考:https://www.jianshu.com/p/359a6e1ccd94

Go chan的底层原理相关推荐

  1. 【golang源码分析】chan底层原理——附带读写用户队列的环形缓冲区

    1 环形缓冲区 1.1 环形缓冲区结构 环形缓冲区通常有一个读指针和一个写指针.读指针指向环形缓冲区中可读的数据,写指针指向环形缓冲区中可写的缓冲区.通过移动读指针和写指针就可以实现缓冲区的数据读取和 ...

  2. channel 的底层原理

    三.channel 的底层原理 前面提及过 channel 创建后返回了 hchan 结构体,现在我们来研究下这个结构体,它的主要字段如下: type hchan struct {qcount uin ...

  3. golang 重要知识:channel 用法和底层原理

    前言 channel 是 goroutine 与 goroutine 之间通信的重要桥梁,借助 channel,我们能很轻易的写出一个多协程通信程序.今天,我们就来看看这个 channel 的常用用法 ...

  4. 没有与参数列表匹配的 重载函数 getline 实例_面试题:方法重载的底层原理?...

    前语:微信改版后,大量读者还没养成点赞的习惯,如写得好,望大家阅读后在右下边"好看"处点个赞,以示鼓励!长期坚持原创真的很不容易,多次想放弃,坚持是一种信仰,专注是一种态度. 关于 ...

  5. synchronized底层原理_你用过synchronized吗?它的底层原理是什么?Java经典面试题来了...

    并发编程已经成为程序员必备技能 作为Java程序员,不懂得并发编程显然已经不能满足市场需求了,尤其是在面试过程中将处于被动地位,也有可能面试将就此终结. 那么作为Java开发者的你,日常虽然可以基于J ...

  6. iOS底层原理 - 常驻线程

    iOS底层原理 - 常驻线程 在 AFN 2.0 时代,会经常看到 AFN 创建一个常驻线程的方式: 0️⃣ AFN 2.0 时代的常驻线程 + (NSThread *)networkRequestT ...

  7. elasticsearch原理_ElasticSearch读写底层原理及性能调优

    ES写入/查询底层原理 1. Elasticsearch写入数据流程 客户端随机选择一个ES集群中的节点,发送POST/PUT请求,被选择的节点为协调节点(coordinating node) 协调节 ...

  8. 嘿嘿,我就知道面试官接下来要问我 ConcurrentHashMap 底层原理了,看我怎么秀他...

    来自:烟雨星空 前言 上篇文章介绍了 HashMap 源码后,在博客平台广受好评,让本来己经不打算更新这个系列的我,仿佛被打了一顿鸡血.真的,被读者认可的感觉,就是这么奇妙. 原文:面试官再问你 Ha ...

  9. 面试官再问你 HashMap 底层原理,就把这篇文章甩给他看

    来自:烟雨星空 前言 HashMap 源码和底层原理在现在面试中是必问的.因此,我们非常有必要搞清楚它的底层实现和思想,才能在面试中对答如流,跟面试官大战三百回合.文章较长,介绍了很多原理性的问题,希 ...

  10. 为了把mysql的索引底层原理讲清楚,我把计算机翻了个底朝天

    来自:非科班的科班 什么是索引 概念:索引是提高mysql查询效率的数据结构.总的一句话概括就是索引是一种数据结构. 数据库查询是数据库的最主要功能之一.设计者们都希望查询数据的速度能尽可能的快,因此 ...

最新文章

  1. 用Kettle的一套流程完成对整个数据库迁移 费元星
  2. Android SystemTrace使用攻略
  3. 牛牛和牛可乐的赌约2
  4. 用html编写一幅简单的画,使用html5画简单的折线图
  5. mysql主从复制的binlog和relay-log的区别
  6. css 实现居中的五种方式
  7. NUC1840 Graveyard Design【尺取法】
  8. Spring的组件自动扫描机制
  9. 一分钟学会看k线图_教你一分钟就能学会看k线图 不信来试 (图文)
  10. css做出京东登录界面
  11. Mac 系统 Arduino IDE 找不到开发板端口的解决方法
  12. Ubuntu 20.04安装绿联PL2303串口驱动
  13. java ftp上传失败_使用java进行ftp文件上传出现425错误
  14. 亲爱的老狼-列表符号怎么放在盒子里
  15. python技术书《Real World Python for learnner 大蟒本色》
  16. HTML\CSS实现静态网页附完整代码【W3school主页】
  17. Android 炫酷的手势动画,16个超级漂亮的手机锁屏图案,炫酷到飞起,总有一款适合你...
  18. 32、网络工程师必知的华为命令大全
  19. IP解析:含义、作用、格式、分类
  20. 圈叉游戏 java_【炫光圈叉棋】炫光圈叉棋 Tic Tac Toe Glow 1.8.1下载_安卓(android)软件下载-魅族溜...

热门文章

  1. 调整swiper底部默认小点的样式
  2. Draco - glTF模型压缩利器
  3. 偶数求和打分 c语言acm,杭州电子科技大学ACM2015-偶数求和-解题思路(accept)
  4. Prometheus Operator开始
  5. 线性代数 【23】 概念的深入01 - Points坐标点和Vectors向量
  6. 【今日小记】程序员的孤独,没人懂
  7. xctf攻防世界 REVERSE 高手进阶区 re2-cpp-is-awesome
  8. asp 在线发送邮件
  9. iPhone 屏幕适配尺寸整理
  10. miui12系统小米系统安卓系统里面存储空间占用太多如何清理