golang channel

channel

在这里插入图片描述

hchan结构

1channel通过make创建后在栈上存指针,数据结构存储在堆上
2 lock–channel要支持并发访问,所以要有锁
2 buf–有缓冲区的channel,需要知道缓冲区的地址
3 qcount–channel已经存储了多少个元素
4 datesize–最多能存储多少个元素
5 slemsize–每个元素占多大空间
6 elemtype–指针,指向元素的元类型
7 sendx,rcvx–读和写的下标位置
8 recvq sendq–读和写队列
9 close–是否close

在这里插入图片描述

sudog结构

1当一个goroutine g1向channel发送数据1-6,发送到第五个channel缓冲区已满,g1进入sendq队列等待
2sudog结构体中的g记录是哪一个g在等待,elem记录等待的元素是什么,hchan记录是哪一个channel
在这里插入图片描述
1当有另一个g2来读取数据,下标为0的数据被拿走,buf有空间,g1的元素6写入,g1从sendq队列移除
2 sendx和recvx都会从0-4循环变化,这杯称为环形缓冲区

在这里插入图片描述

多路select

1select实际是调用runtime.selectgo()的调用
2 cas0—数组,里面是所有的case分支,send在前,recv在后(以case聚合)
3 order0—数组,分两部分,第一部分是所有channel的轮询乱序,第二个数组是枷锁顺序
4 nrecvs nsends----所有case操作中执行send和recv的操作分别有多少个(以send和recv聚合)
5 block—是否阻塞,对应到代码中就是有default不会阻塞,没有default则阻塞
6 返回值int----标识最终那个case分支被执行了,对应到cas0数组的下标,如果是default分支则是-1
7 返回值bool—标识recv操作时,是实际接受到了一个值,还是因channel关闭而接收到了0值

在这里插入图片描述

1goroutine执行channel时,会以乱序检测那个case分支可以执行了,但会先按照顺序对所有channel枷锁,乱序检查所有channel的等待队列(recvq,sendq)和缓冲区(buf)
2 加入检测ch1缓冲区有数据可读,就拷贝数据进入对应case分支
3假如ch1 recvq没空,ch2sendq已满,标识没有可执行的case,则g1会被添加到ch1的recvq和ch2的sendq中,g1倍挂起
4 g1挂起后解锁所有是channel
4 加入ch1有数据可读,g1再次唤醒,完成对应的case分支
5 按序枷锁
6 g1将自己从等待队列中(sendq,recvq)移除
7 全部解锁channel,返回

sudoG 结构体:
// sudog 代表在等待列表里的 g,比如向 channel 发送/接收内容时

// 之所以需要 sudog 是因为 g 和同步对象之间的关系是多对多的

// 一个 g 可能会在多个等待队列中,所以一个 g 可能被打包为多个 sudog

// 多个 g 也可以等待在同一个同步对象上

// 因此对于一个同步对象就会有很多 sudog 了

// sudog 是从一个特殊的池中进行分配的。用 acquireSudog 和 releaseSudog 来分配和释放 sudog

send

在这里插入图片描述
不阻塞—执行case分支
阻塞------执行default分支

rcv

在这里插入图片描述
在这里插入图片描述
send和recv操作底层是调用了euntime.chansend()和runtime.chanrecv()

runtime等待队列-semaphore信号量

在这里插入图片描述
多核–锁住总线

解决锁定问题:
1
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
1 通过结构体中记录数值的变量sema计算尺地址映射到sematable上
2 通过地址找到对应节点,就找到了这个节点所在的等待队列
通过sync.Mutex.sema计算映射daosematable的index,就找到了根节点,再在设个平衡树上找到对应节点的等待队列
在这里插入图片描述
semaphore和channel的等待队列底层都是mutex

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值