go channel源码解析


写在前面

在面试过程中经常会被问到有没有阅读过go源码,前面写了一篇文章go slice扩容是怎么计算大小的 专门针对这个问题的,学了这篇文章你就可以跟面试官说阅读过go源码,并且将他引导到go slice扩容的地方。

go slice的扩容的源码是代码量最少、逻辑最简单的部分源码,入手快,防止面试尴尬。如果面试官继续问:还阅读过其他源码吗?你该怎么回答呢?今天就带大家阅读难度系数很低的go channel源码。(慢慢递进,后面会有map,sync,time相关的源码阅读)

channel源码怎么读

当面试官问go channel源码的时候他在问什么?其实他是在问channel的结构定义。channel没有扩容,接收、发送数据逻辑也都很简单,跟源码没有关系,都是基础知识,去学一下就行。看完这两篇文章就基础知识就差不多了深入理解 go chango chan 设计与实现

源码

type hchan struct {
   qcount   uint           // 缓冲区(环形队列)元素个数
   dataqsiz uint           // 缓冲区的大小(最多可容纳的元素个数)
   buf      unsafe.Pointer // 指向缓冲区入口的指针(从 buf 开始 qcount * elemsize 大小的内存就是缓冲区所用的内存)
   elemsize uint16         // chan 对应类型元素的大小(主要用以计算第 i 个元素的内存地址)
   closed   uint32         // chan 是否已经关闭(0-未关闭,1-已关闭)
   elemtype *_type         // chan 的元素类型
   sendx    uint           // chan 发送操作处理到的位置
   recvx    uint           // chan 接收操作处理到的位置
   recvq    waitq          // 等待接收数据的协程队列(双向链表)
   sendq    waitq          // 等待发送数据的协程队列(双向链表)

   // 锁
   lock mutex
}

hchan有11个属性,记住这11个属性就和相关的基础知识,就可以说阅读过go chan源码了。

记忆方法:

  • 先记最重要的4个属性
       - buf:指向存储数据的环形队列的指针
       - recvq:发送队列
       - sendq:接收队列
       - lock:锁
    上面这个很容易记,记住chan里面有3个队列+1个锁就行,三个队列分别是:数据队列、发送队列、接收队列
  • 然后记住buf相关的7个熟悉
       - qcount:数据队列中元素数量
       - dataqsiz:数据队列容量
       - elemtype:元素类型
       - elemsize:元素大小
       - recvx:接收指针
       - sendx:发送指针
       - closed:是否关闭

如果面试官问有没有阅读过go chan的源代码,就说读过,go chan有11个属性,它的读写都是围绕着这11个属性实现的。

参考

[1] 深入理解 go chan

[2] go chan 设计与实现

[3] go slice扩容是怎么计算大小的

br>


文章作者: Alex
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Alex !
  目录