06-go数据类型内存结构-chan

22 篇文章 1 订阅
8 篇文章 1 订阅

5. chan

var var_chan = make(chan int ,1)
func func1(){
...
var var2_chan = make(chan int ,3)
...
}

1、通过runtime.makechan()创建channel。

2、第一个参数为chan类型信息
3、返回值类型为*hchan
即: chan变量实际为一个hchan指针
由全局变量也可以看出。

func makechan(t *chantype, size int) *hchan {
    ...
    var c *hchan
    ...
    return c
}
"".var_chan SBSS size=8
0x014f 00335 (type.go:48)       LEAQ    type.chan int(SB), AX
0x0156 00342 (type.go:48)       PCDATA  $2, $0
0x0156 00342 (type.go:48)       MOVQ    AX, (SP)
0x015a 00346 (type.go:48)       MOVQ    $3, 8(SP)
0x0163 00355 (type.go:48)       CALL    runtime.makechan(SB)
0x0168 00360 (type.go:48)       PCDATA  $2, $1
0x0168 00360 (type.go:48)       MOVQ    16(SP), AX  //返回值为 *hchan 类型
0x016d 00365 (type.go:48)       PCDATA  $2, $0
0x016d 00365 (type.go:48)       PCDATA  $0, $5
0x016d 00365 (type.go:48)       MOVQ    AX, "".var2_chan+144(SP)

chan类型信息

type chantype struct {  //64 字节
	typ  _type      //48 字节
	elem *_type     //8  字节
	dir  uintptr    //8 字节
}

类型信息对应汇编

type..namedata.*chan int- SRODATA dupok size=12
        0x0000 00 00 09 2a 63 68 61 6e 20 69 6e 74              ...*chan int
type.*chan int SRODATA dupok size=56
        0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
        0x0010 ed 7b ed 3b 00 08 08 36 00 00 00 00 00 00 00 00  .{.;...6........
        0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
        0x0030 00 00 00 00 00 00 00 00                          ........
        rel 24+8 t=1 runtime.algarray+80
        rel 32+8 t=1 runtime.gcbits.01+0
        rel 40+4 t=5 type..namedata.*chan int-+0
        rel 48+8 t=1 type.chan int+0
type.chan int SRODATA dupok size=64
        0x0000 08 00 00 00 00 00 00 00 08 00 00 00 00 00 00 00  ................
        0x0010 91 55 cb 71 02 08 08 32 00 00 00 00 00 00 00 00  .U.q...2........
        0x0020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
        0x0030 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00  ................
        rel 24+8 t=1 runtime.algarray+80
        rel 32+8 t=1 runtime.gcbits.01+0
        rel 40+4 t=5 type..namedata.*chan int-+0
        rel 44+4 t=6 type.*chan int+0
        rel 48+8 t=1 type.int+0
5.1 通过runtime.makechan
src\runtime\chan.go
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 {
	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.kind&kindNoPointers != 0:
		// 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:
		// Elements contain pointers.
		c = new(hchan)
		c.buf = mallocgc(mem, elem, true)
	}

	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、付费专栏及课程。

余额充值