channel 底层

题目来源:七牛

答案:

参考《Go 语言底层原理剖析》

Go 语言的理念是通过通信来实现共享内存。Go 的CSP,通信顺序进程,是通过goroutine和channel来实现的。

405.channel 底层 - 图1

如上图所见:

通道在运行时是一个特殊的hchan结构体,

  1. type hchan struct{
  2. qcount uint 通道队列中的数据个数
  3. dataqsiz uint 通道队列中数据的大小
  4. buf unsafe.Pointer 存放实际数据的指针
  5. elemsize uint16 通道类型的大小
  6. closed uint32 通道是否关闭
  7. elemtype *_type 通道类型
  8. sendx uint 记录发送者在buf中的序号(记录往channel中写入数据的下一个位置)
  9. recvx uint 记录接收者在buf中的序号 (从channel中读取数据的下一个位置)
  10. recvq waitq 读取的阻塞协程队列
  11. sendq waitq 写入的阻塞协程队列
  12. lock mutex 锁,并发保护
  13. }

对于有缓冲的通道,存储在buf中的数据虽然是线性的数组,但是用数组和序号recvx,sendx模拟了一个环形队列。recvx可以找到从buf中哪个位置获取通道中的元素,而sendx能够找到写入时放到buf的位置,这样做主要是为了重用已经使用过的空间。recvx到sendx的距离代表通道队列中的元素数量。