1.chan数据结构
一个channel只能传递一种类型的值,类型信息存储在hchan数据结构中。
- elemtype代表类型,用于数据传递过程中的赋值;
- elemsize代表类型大小,用于在buf中定位元素位置。
一个channel同时仅允许被一个goroutine读写,为简单起见,本章后续部分说明读写过程时不再涉及加锁和解锁。
2.创建Chan
创建channel的过程实际上是初始化hchan结构。其中类型信息和缓冲区长度由make语句传入,buf的大小则与元素大小和缓冲区长度共同决定。
makeChan源码如下:
func makechan(t *chantype, size int) *hchan {
elem := t.elem
// compiler checks this but be safe.
if elem.size >= 1<<16 {
throw(\"makechan: invalid channel element type\")
}
if hchanSize%maxAlign != 0 || elem.align > maxAlign {
throw(\"makechan: bad alignment\")
}
mem, overflow := math.MulUintptr(elem.size, uintptr(size))
if overflow || mem > maxAlloc-hchanSize || size < 0 {
panic(plainError(\"makechan: size out of range\"))
}
// Hchan does not contain pointers interesting for GC when elements stored in buf do not contain pointers.
// buf points into the same allocation, elemtype is persistent.
// SudoG\'s are referenced from their owning thread so they can\'t be collected.
// TODO(dvyukov,rlh): Rethink when collector can move allocated objects.
var c *hchan
switch {
// no buffer 的场景,这种 channel 可以看成 pipe;
case mem == 0:
// Queue or element size is zero.
c = (*hchan)(mallocgc(hchanSize, nil, true))
// Race detector uses this location for synchronization.
c.buf = c.raceaddr()
case elem.ptrdata == 0:// channel 元素不含指针的场景,那么是分配出一个大内存块;
// Elements do not contain pointers.
// Allocate hchan and buf in one call.
c = (*hchan)(mallocgc(hchanSize+mem, nil, true))
c.buf = add(unsafe.Pointer(c), hchanSize)
default:// 默认场景,hchan 结构体和 buffer 内存块单独分配;
// Elements contain pointers.
c = new(hchan)
c.buf = mallocgc(mem, elem, true)
}
// channel 元素大小,如果是 int,那么就是 8 字节;
c.elemsize = uint16(elem.size)
// 元素类型,这样就知道 channel 里面每个元素究竟是啥
c.elemtype = elem
c.dataqsiz = uint(size)
lockInit(&c.lock, lockRankHchan)
if debugChan {
print(\"makechan: chan=\", c, \"; elemsize=\", elem.size, \"; dataqsiz=\", size, \"\\n\")
}
return c
}
makeChan只会初始化四个参数:buf,elemsize,elemtype,dataqsize
channel发送的代码解析如下:
channel接收数据的代码如下:
来源:https://www.cnblogs.com/lisus2000/p/17073385.html
本站部分图文来源于网络,如有侵权请联系删除。