-
底层是hchan,数据存储在buf指针字段指向的环形队列中(有缓冲chan),recex字段表示环形数组头位置,sendx表示环形数组尾位置,阻塞读goroutine挂在recvq指针字段,阻塞写goroutine挂在sendq指针字段,阻塞队列waitq底层是sudog链表,sudog是g的封装,sudog中的elem记录要存取的元素地址
-
初始化makechan()分3case,
- 无缓冲或元素为0仅分配hchan
- 有缓冲元素不含指针hchan与buf一起分配
- 有缓冲元素包含指针,hchan与buf分开分配
-
写入chansend()分5case
- 有读等待recvg则弹出sudog互斥写再唤醒g
- 无recvg但有不满buf则互斥写入buf
- 无recv且buf满则写入sudog挂sendq互斥写再挂起该g
- channel为nil g永久挂起或main退出
- channel已关闭会panic。
-
读出chanrecv()分4case
- 有sendq则弹出sudog,无buf直接互斥读再唤醒g,有buf则读互斥读buf且sudog写入buf唤醒g
- 无sendq且buf有数据则互斥读buf
- 无sendq且buf无数据则写入sudog挂recvq并挂起该g
- channel关闭则取recvq和sendq所有sudog加入glist唤醒所有g(关闭nil的chan与重复关闭chan会panic)
-
select随机,有default可防止阻塞,无default会挂起并挂在所有chan的waitq中,再被一个chan唤醒则删除其他所有
Channel底层简记
于 2024-01-01 16:56:17 首次发布