type hchan struct {
qcount uint
dataqsiz uint //channel的大小
buf unsafe.Pointer
elemsize uint16
closed uint32
elemtype *_type
sendx uint
recvx uint
recvq waitq
sendq waitq
lock mutex
}
hchan只是一个头部,如果hchan不包含指针则add(unsafe.Pointer(c), hchanSize)后面则是对应的buf,否则则是newarray(elem, int(size)),后面是一组长度为int(size)类型为elem的指针。
func reflect_makechan(t *chantype, size int64) *hchan {
return makechan(t, size)
}
func makechan(t *chantype, size int64) *hchan { //size为chan的容量cap
elem := t.elem //elem类似于*int这种
if elem.size >= 1<<16 {
throw("makechan: invalid channel element type")
}
if hchanSize%maxAlign != 0 || elem.align > maxAlign {
throw("makechan: bad alignment")
}
if size < 0 || int64(uintptr(size)) != size || (elem.size > 0 && uintptr(size) > (_MaxMem-hchanSize)/elem.size) {
panic(plainError("makechan: size out of range"))
}
var c *hchan
if elem.kind&kindNoPointers != 0 || size == 0 {//如果没有指针或者长度为0
//申请内存,如果没有缓冲区的chan则size为0,就是hchansize大小
c = (*hchan)(mallocgc(hchanSize+uintptr(size)*elem.size, nil, true))
if size > 0 && elem.size != 0 {
c.buf = add(unsafe.Pointer(c), hchanSize)//存在缓冲区,则buf从hchansize后面开始
} else {
c.buf = unsafe.Pointer(c)
}
} else {
c = new(hchan)
c.buf = newarray(elem, int(size))//申请一组大小为size,类型为elem的指针数组
}
c.elemsize = uint16(elem.size)//指针的大小
c.elemtype = elem //类型
c.dataqsiz = uint(size)//容量
if debugChan {
print("makechan: chan=", c, "; elemsize=", elem.size, "; elemalg=", elem.alg, "; dataqsiz=", size, "\n")
}
return c
}