首页 > 其他分享 >Go chan解析

Go chan解析

时间:2023-01-29 18:22:22浏览次数:27  
标签:chan elem makechan hchan Go 解析 buf channel size

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发送的代码解析如下:

 


 

 

 

 

 

 

 

 

标签:chan,elem,makechan,hchan,Go,解析,buf,channel,size
From: https://www.cnblogs.com/lisus2000/p/17073385.html

相关文章

  • ORM哪家强?java,c#,php,python,go 逐一对比, 网友直呼:全面客观
    前言最近一段时间,我使用​​golang​​开发了一个新的​​ORM​​库。为了让这个库更好用,我比较研究了各语言的主流​​ORM​​库,发现有一些语言的​​ORM​​库确实很好用,......
  • Go 生成伪随机数
    packagemainimport( "fmt" "math/rand" "time")funcmain(){ //利用系统时间生成种子 rand.Seed(time.Now().Unix()) //生成[0,n)的随机数 fmt.Println......
  • debian中显示logo 命令
    如图  安装sudoaptinstalllinuxlogo然后linuxlogo-Ldebian 还可以查看有哪些logolinuxlogo-Llist biru  he 可以循环输出看一下,两......
  • django 自定义模板标签
    故事的背景比较复杂,框架用的django,后台用的simpleui,当我在往前端嵌入echarts的时候发现自定义标签返回的list里面的单引号进行了自动转义,变成了&#39; 具体可以参考:ht......
  • GO 操作时间
    packagetimerimport("fmt""time")var(BackOffset=-1*time.Millisecond)typeTimeRangestruct{Starttime.TimeEndtime.Time}func(sTimeRange......
  • django Orm group by
    在django的orm里面想要groupby一个模型的时候遇到一个问题,根据官方文档的调教,怎么都没办法。1、ormmodelclassCvmAlarmDataByMetric(models.Model):"""cv......
  • 【Linux命令----版本升级】Golang 在linux升级版本
    原文:http://turbock79.cn/?p=3859在vscode中使用go1.15模块智能加载显示代码时,存在问题,可能是兼容性或其他问题。通过升级golang到1.16以上,可以实现VScode自动加载的正......
  • ORM哪家强?java,c#,php,python,go 逐一对比, 网友直呼:全面客观
    前言最近一段时间,我使用golang开发了一个新的ORM库。为了让这个库更好用,我比较研究了各语言的主流ORM库,发现有一些语言的ORM库确实很好用,而有另外一些语言的库那不是一般......
  • ReplaceGoogleCDN扩展功能使用二:拦截请求域名
    文档说明:只记录关键地方;2023-01-29使用例子:例子:拦截访问域名https://www.jingjingxyk.com更多玩法,可配合content_scripts实现清除内容农场规则例子[{......
  • k8s client-go 02基础clientset操作k8s
    Clientset构造clientset操作k8s集群。packagemainimport("context""fmt"v1"k8s.io/apimachinery/pkg/apis/meta/v1""k8s.io/client-go/ku......