🪝Golang channel

type
status
date
slug
summary
tags
category
icon
password
Blocked by
Blocking
AI summary

数据结构

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

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

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

关闭

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