🪝Golang channel
type
status
date
slug
summary
tags
category
icon
password
Blocked by
Blocking
AI summary
数据结构
channel的地层数据结构为
hchan

waitq为阻塞的协程队列
sudog用于包装协程的节点
其中的 mutex 是runtime包中,给系统运行时使用的互斥锁,使用更加地层,其直接基于semaphore原语
- 0表示未锁定
- 1表示锁定
- 其他值表示有等待者
每次调用semaphore不一定都陷入内核态,go的运行时做了很多优化
- 无竞争时,完全在用户态解决
- 有竞争时,尝试用内核态自自旋
- 如果都无法解决时,才会使用真正的信号量陷入内核态
读

- 看channel是否为nil,若为nil,直接deadlock
- 若channel不为nil,则用mutex 锁住
- 检查channel是否有close
- 若有close
- 若buf中是否还有元素,若有直接返回数据,解锁mutex
- 若buf中无元素,则返回channel 数据的zero value
- 若无close
- 写入阻塞队列中无元素
- 若buf中有元素,读取数据,返回
- 若buf中无元素且写入阻塞队列中无元素,将此读取协程加入此channel的readq中,go_park,协程进入阻塞状态,解锁mutex
- 写入阻塞协程队列中有元素,从阻塞写入协程链表中第一个协程唤醒,读取数据,解锁mutex,返回数据
写

- 若channel为nil,写入不成功,panic
- 若channel已经closed,panic
- mutex
- 若channel的buf还有空间,直接写入数据,返回
- 若读取阻塞协程队列不为空,从读取阻塞队列中读取数据,返回
- 若buf中无空间且读取阻塞队列中无元素,将g加入写入阻塞队列,调用go_park,进入阻塞状态
关闭

- 若channel为nil,关闭失败,发生panic
- channel不为nil,使用mutex锁住
- 若channel已经close,此时再close,就发生了重复close事件,panic
- 将所有的读取阻塞协程唤醒
- 若写入阻塞协程还存在,则发生panic
- mutex解锁`
Prev
正则表达式
Next
如何避免channel重复关闭
Loading...