chan实际结构是runtime.hchan(https://github.com/golang/go/blob/master/src/runtime/chan.go)
type hchan struct {
qcount uint // total data in the queue
dataqsiz uint // size of the circular queue
buf unsafe.Pointer // points to an array of dataqsiz elements
elemsize uint16
closed uint32
elemtype *_type // element type
sendx uint // send index
recvx uint // receive index
recvq waitq // list of recv waiters
sendq waitq // list of send waiters
// lock protects all fields in hchan, as well as several
// fields in sudogs blocked on this channel.
//
// Do not change another G's status while holding this lock
// (in particular, do not ready a G), as this can deadlock
// with stack shrinking.
lock mutex
}
qcount: chan 中已经接收但还没被取走的元素的个数。内建函数 len 可以返回这个字段的值。
dataqsiz:队列的大小。chan 使用一个循环队列来存放元素。
buf:存放元素的循环队列的 buffer
elemsize:buffer中元素大小
closed:是否close
elemtype:buffer中元素类型
sendx:处理发送数据的指针在 buf 中的位置。一旦接收了新的数据,指针就会加上 elemsize,移向下一个位置。buf 的总大小是 elemsize 的整数倍,而且 buf 是一个循环列表。
recvx:处理接收请求时的指针在 buf 中的位置。一旦取出数据,此指针会移动到下一个位置。
recvq:receiver等待队列。chan 是多生产者多消费者的模式,如果消费者因为没有数据可读而被阻塞了,就会被加入到 recvq 队列中。
sendq:sender等待队列。如果生产者因为 buf 满了而阻塞,会被加入到 sendq 队列中。
有疑问加站长微信联系(非本文作者)