chan

数据结构

类似于管道,可以并发读写。不可以向已关闭chan写入数据。

// runtime/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
    sendx    uint   // send index
    recvx    uint   // receive index

    elemsize uint16
    closed   uint32
    elemtype *_type // element type

    // 读写等待队列
    recvq    waitq  // list of recv waiters
    sendq    waitq  // list of send waiters

    // lock protects all fields in hchan, as well as several
    // fields in sudogs blocked on this channel.
    //
    // Do not change another G's status while holding this lock
    // (in particular, do not ready a G), as this can deadlock
    // with stack shrinking.
    lock mutex
}

实现

直接搬运代码,专注细节容易绕晕。大致每个功能需要考虑几种边界条件

阻塞/非阻塞
缓冲区为空/非空
缓冲区满/非满
读写等待队列空/非空
chan为nil/非nil

1、单chan读/写(runtime/chan.go:chanrecv/chansend)


2、关闭chan(runtime/chan.go:closechan)。加锁;唤醒读/写等待队列全部任务;解锁

3、多个chan同时读/写(runtime/select.go:selectgo)。大致思路就是打乱case顺序;对全部chan加锁;遍历找出第一个读/写准备好的任务;逆序解锁

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • GO 中 Chan 实现原理分享 嗨,我是小魔童哪吒,还记得咱们之前分享过GO 通道 和sync包的使用吗?咱们来...
    阿兵云原生阅读 442评论 0 5
  • 1)chan结构体-hchan channel内部是固定长度的双向循环链表,make时确认size大小 环形队列有...
    hapcat阅读 270评论 0 0
  • chan是go中csp的关键,网上一直说chan性能一般,因为用到了锁,我就找来源码研究了一下 我们先看chan对...
    柯基是只dog阅读 974评论 0 1
  • chan数据结构 环形队列 创建有缓冲区channel时,如下: 等待队列 channel读写操作: 读:无缓冲区...
    LitC阅读 619评论 0 1
  • 本篇文章内容基于go1.14.2分析 golang的chan是一个内置类型,作为csp编程的核心数据结构,其底层数...
    litesky阅读 320评论 0 0