跳到主要内容

Go 源码学习 --- chan

· 阅读需 2 分钟
ahKevinXy

hchan


type hchan struct {
qcount uint // 通道中的总数据 total data in the queue
dataqsiz uint // 循环队列的大小 size of the circular queue
buf unsafe.Pointer // 指向dataqsiz元素数组 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 // 锁
}

type waitq struct {
first *sudog // 第一个
last *sudog // 最后一个
}
type sudog struct {
// The following fields are protected by the hchan.lock of the
// channel this sudog is blocking on. shrinkstack depends on
// this for sudogs involved in channel ops.

g *g

next *sudog // 下一个
prev *sudog // 上一个
elem unsafe.Pointer // 数据元素(可能指向堆栈) data element (may point to stack)

// The following fields are never accessed concurrently.
// For channels, waitlink is only accessed by g.
// For semaphores, all fields (including the ones above)
// are only accessed when holding a semaRoot lock.

acquiretime int64 //
releasetime int64 //
ticket uint32 //

// isSelect indicates g is participating in a select, so
// g.selectDone must be CAS'd to win the wake-up race.
isSelect bool

// success indicates whether communication over channel c
// succeeded. It is true if the goroutine was awoken because a
// value was delivered over channel c, and false if awoken
// because c was closed.
success bool //是否成功

parent *sudog // semaRoot二叉树 semaRoot binary tree
waitlink *sudog // g.等待列表或semaRoot g.waiting list or semaRoot
waittail *sudog // 等待 semaRoot
c *hchan // 通道 channel
}