· 104字 · 1分钟

channel 🔗

graph LR
    1(channel) --> 2(向 channel 发送消息)
    1 --> 3(接受消息)
    1 --> 4(关闭channel)
    2 -- full channel--> 5(阻塞)
    2 --closed channel--> 6(panic)
    3 --empty channel-->5
    3 --closed channel--> 7(读到零值)
    4 --closed/nil channel--> 6
 graph TB
    1(向 channel 发送消息) --> 2{channel 是否 nil} --否--> 4{channel 是否 closed}--否--> 6{recvq 队列是否存在值}--否-->8{buf 是否未满} --否--> 10(阻塞协程,并放到 sendq 队列中)
2 --是--> 3(阻塞)
    4  --是--> 5(panic)
    6 --是--> 7(队首出队,消息直接发送至该 goroutine 中)
    8--是--> 9(消息拷贝到 buf sendx位置中,等待唤醒)
graph TB
    1(向channel接受消息) --> 2{channel是否nil} --否--> 4{channel是否closed && buf中元素为空}--否--> 6{sendq队列是否存在值}--否-->8{buf 是否为空} --是--> 10(阻塞协程,并放到recvq队列中)
2 --是--> 3(阻塞)
    4  --是--> 5(返回零值)
    6 --是--> 7(sendq队首出队) --无缓冲channel--> 11(将出队goroutine发送的消息拷贝到返回数据)
    7 --缓冲channel--> 12(将buf队首消息copy到返回数据) --> 13(再将sendq出队的goroutine发送消息拷贝到buf)
    8--否--> 9(将 buf 队首消息 copy 到返回数据)