知识卡片

阻塞会让出G

结构图卡 · 1482.a.1

内容

发送或接收无法立即完成时,当前 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链表末尾,并且当前协程陷入休眠状态,等待被唤醒重新执行。