Go小技巧（一）— 获取channel属性

sipt · · 2876 次点击 · · 开始浏览

概述

channel的结构体在chan.go中：

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
//... 以下字段没有用上，先省略
}

• qcount：queue里的数据总数
• dataqsiz：queue的最大长度
• closed：是否关闭

实现

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
}

type eface struct {
_type *_type
data  unsafe.Pointer
}

i := (*[2]uintptr)(unsafe.Pointer(&c))
h := (*hchan)(unsafe.Pointer(i[1]))

附录

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
}
type ChanInfo struct {
Closed bool  // 是否关闭
Len    uint  // channel内数据量
Cap    uint  // channel容量
Block  bool  // 是否已经阻塞
}

func ChanStatus(c interface{}) (*ChanInfo, error) {
v := reflect.ValueOf(c)
if v.Type().Kind() != reflect.Chan {
return nil, errors.New("type must be channel")
}
i := (*[2]uintptr)(unsafe.Pointer(&c))
h := (*hchan)(unsafe.Pointer(i[1]))
return &ChanInfo{
Cap:    h.dataqsiz,
Len:    h.qcount,
Closed: h.closed == 1,
Block:  h.qcount >= h.dataqsiz,
}, nil
}

1 回复  |  直到 2020-09-03 18:25:40

• 请尽量让自己的回复能够对别人有帮助
• 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
• 支持 @ 本站用户；支持表情（输入 : 提示），见 Emoji cheat sheet
• 图片支持拖拽、截图粘贴等方式上传

概述

channel的结构体在chan.go中：

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
//... 以下字段没有用上，先省略
}

• qcount：queue里的数据总数
• dataqsiz：queue的最大长度
• closed：是否关闭

实现

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
}

type eface struct {
_type *_type
data  unsafe.Pointer
}

i := (*[2]uintptr)(unsafe.Pointer(&c))
h := (*hchan)(unsafe.Pointer(i[1]))

附录

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
}
type ChanInfo struct {
Closed bool  // 是否关闭
Len    uint  // channel内数据量
Cap    uint  // channel容量
Block  bool  // 是否已经阻塞
}

func ChanStatus(c interface{}) (*ChanInfo, error) {
v := reflect.ValueOf(c)
if v.Type().Kind() != reflect.Chan {
return nil, errors.New("type must be channel")
}
i := (*[2]uintptr)(unsafe.Pointer(&c))
h := (*hchan)(unsafe.Pointer(i[1]))
return &ChanInfo{
Cap:    h.dataqsiz,
Len:    h.qcount,
Closed: h.closed == 1,
Block:  h.qcount >= h.dataqsiz,
}, nil
}