Channel
Go 中 channel 中用法和实现总结 以下分析和源码都是基于 go1.17 版本 channel 简介 Go 语言的基础类型之一, 用于在协程与协程之间传递数据 (channel 数据的传输方式也是值传递, Go语言的数据传输只有值传递) Do not communicate by sharing memory; instead, share memory by communicating. channel 保证: 数据的先入先出 并发情况下的数据安全 已经关闭的 channel 不可重开 channel 的实现 channel 在内部实现的结构体为 runtime.hchan 有一个环形链表, 暂存要传输的数据. 无 buffer 的channel 该队列长度为0, 所以不进行数据缓冲. 有一把互斥锁mutex, 在并发情况下, 保护自身数据结构的一致性 有两个协程等待链表, 用于挂载因为发送/接收而阻塞在该 channel 上的协程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 type hchan struct { qcount uint // 当前 buffer 中有暂存着多少个数据 dataqsiz uint // 环形数组的buffer个数, 由 make 初始化的时候第二个参数容量决定的 buf unsafe.Pointer // 环形数组开始地址 elemsize uint16 // channel 传输的元素大小, 用于计算内存大小 closed uint32 // channel 是否已经关闭 0未关闭, 非0关闭 elemtype *_type // element type # channel 元素的类型 sendx uint // 环形链表中, 发送数据存储的下标 recvx uint // 环形链表中, 接受数据获取数据的下标 recvq waitq // 阻塞在该 channel 等待获取数据的 Groutine 列表 sendq waitq // 阻塞在该 channel 等待写入数据的 Groutine 列表 lock mutex // # 互斥锁 用于保护自身数据变更 } 初始化 channel 传递的元素不能太大 如果是空结构体或者无缓冲队列, 是不需要分配环形队列内存 如果传递数据类型有内含指针, 需要将环形队列分配到堆上 内部实现函数runtime.makechan ...