Go语言——channel详解

栏目: Go · 发布时间: 5年前

内容简介:参考:channel和goroutine是go语言最具特色是结构,有必要仔细研究。

Go语言——channel详解

参考:

深入理解Golang 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

Go语言——channel详解

send & revc

send

recv


以上所述就是小编给大家介绍的《Go语言——channel详解》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

复盘+:把经验转化为能力(第2版)

复盘+:把经验转化为能力(第2版)

邱昭良 / 机械工业出版社 / 39.00

随着环境日趋多变、不确定、复杂、模糊,无论是个人还是组织,都需要更快更有效地进行创新应变、提升能力。复盘作为一种从经验中学习的结构化方法,满足了快速学习的需求,也是有效进行知识萃取与共享的机制。在第1版基础上,《复盘+:把经验转化为能力》(第2版)做了六方面修订: ·提炼复盘的关键词,让大家更精准地理解复盘的精髓; ·基于实际操作经验,梳理、明确了复盘的"底层逻辑"; ·明确了复......一起来看看 《复盘+:把经验转化为能力(第2版)》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

Markdown 在线编辑器
Markdown 在线编辑器

Markdown 在线编辑器

html转js在线工具
html转js在线工具

html转js在线工具