golang中channel的底层实现

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
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值