内容简介:参考:channel和goroutine是go语言最具特色是结构,有必要仔细研究。
Go语言——channel详解
参考:
channel和goroutine是 go 语言最具特色是结构,有必要仔细研究。
源码路径:go1.10\src\runtime\chan.go
struct
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 mutex }
- qcount:当前chann元素个数,len()
- dataqsiz:chann容量,cap()
- buf:元素缓冲区
- elemsize:元素大小
- closed:close标志位
- elemtype:元素类型
- sendx:下一个发送元素所在缓冲区索引
- recvx:下一个接收元素所在缓冲区索引
- recvq:接收G的等待队列
- sendq:发送G的等待队列
从上面可以看出, waitq
非常重要
type waitq struct { first *sudog last *sudog } type sudog struct { g *g isSelect bool next *sudog prev *sudog elem unsafe.Pointer // data element (may point to stack) acquiretime int64 releasetime int64 ticket uint32 parent *sudog // semaRoot binary tree waitlink *sudog // g.waiting list or semaRoot waittail *sudog // semaRoot c *hchan // channel }
waitq
是一个queue,具有头尾指针。
sudog
封装了等待chann接收/发送的G。
new
chan不能直接new,只能make,所以观察makechan方法。make的时候,会根据size判断是缓冲chan还是非缓冲chan,这个逻辑需要注意。
func makechan(t *chantype, size int) *hchan { elem := t.elem // 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 { case size == 0 || elem.size == 0: // Queue or element size is zero. c = (*hchan)(mallocgc(hchanSize, nil, true)) // Race detector uses this location for synchronization. c.buf = unsafe.Pointer(c) case elem.kind&kindNoPointers != 0: // Elements do not contain pointers. // Allocate hchan and buf in one call. c = (*hchan)(mallocgc(hchanSize+uintptr(size)*elem.size, nil, true)) c.buf = add(unsafe.Pointer(c), hchanSize) default: // Elements contain pointers. c = new(hchan) c.buf = mallocgc(uintptr(size)*elem.size, elem, true) } c.elemsize = uint16(elem.size) c.elemtype = elem c.dataqsiz = uint(size) return c }
这里看到由于要对buf对象分配,所以没有提供new方法,只能make。除了对default情况比较容易理解,另外两只buf的内存分配都不是很理解=。=,先遗留。
send & revc
send & revc
send
recv
以上所述就是小编给大家介绍的《Go语言——channel详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
设计模式
[美] Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides / 李英军、马晓星、蔡敏、刘建中 等 / 机械工业出版社 / 2000-9 / 35.00元
这本书结合设计实作例从面向对象的设计中精选出23个设计模式,总结了面向对象设计中最有价值的经验,并且用简洁可复用的形式表达出来。书中分类描述了一组设计良好、表达清楚的软件设计模式,这些模式在实用环境下特别有用。此书适合大学计算机专业的学生、研究生及相关人员参考。 书中涉及的设计模式并不描述新的或未经证实的设计,只收录了那些在不同系统中多次使用过的成功设计。一起来看看 《设计模式》 这本书的介绍吧!