知识卡片
阻塞会让出G
内容
发送或接收无法立即完成时,当前 G 会进入等待队列并让出执行权;匹配操作到来后再被唤醒。channel 的“阻塞”不是线程空转,而是调度器可管理的等待。
结构图:
sequenceDiagram
participant G as 当前G
participant C as channel
participant Q as 等待队列
participant S as 调度器
G->>C: 发送或接收
C->>Q: 无匹配操作则入队
G->>S: 让出执行权
C-->>G: 匹配到来后唤醒
参考来源
- 位置:《Go语言底层原理剖析》第16章《通道与协程间通信》16.4.3、16.4.4节《通道写入原理》《通道读取原理》
- 结论依据:原文说明写入时"如果当前通道无缓冲区或者当前缓冲区已经满了,则代表当前协程的sudog结构需要放入sendq链表末尾中,并且当前协程陷入休眠状态,等待被唤醒重新执行";读取时对称地"如果当前通道无缓冲区或者当前缓冲区已经空了,则代表当前协程的sudog结构需要放入recvq链表末尾,并且当前协程陷入休眠状态",因此可以推出"发送/接收无法立即完成时,G 被封装为 sudog 放入等待队列并让出执行权,匹配到来后被唤醒"的结论。
- 原始内容:如果当前通道无缓冲区或者当前缓冲区已经满了,则代表当前协程的sudog结构需要放入sendq链表末尾中,并且当前协程陷入休眠状态,等待被唤醒重新执行……如果当前通道无缓冲区或者当前缓冲区已经空了,则代表当前协程的sudog结构需要放入recvq链表末尾,并且当前协程陷入休眠状态,等待被唤醒重新执行。