channel

发布时间 2023-10-08 14:57:12作者: 柒染丨

要点:

1 Channel带不带缓冲

2 谁在发

3 谁在收

4 谁来关

5 关了没

 

Channel有buffer和没有buffer的特点

不带缓冲:要求收发两端都必须要有goroutine否则就是阻塞

有buffer:缓冲没满或者没空之前都不会阻塞,缓冲满了或者空了就会阻塞

 

没有初始化的channel为nil channel 发送和接收都会阻塞

向已经关闭的Channel发送数据会panic 接收数据会返回0

 

channel使用不当会导致goroutine泄露

1只发送不接受,发送者一直阻塞会导致泄露

2只接收不发送,接收值一直阻塞会导致泄露

3读写nil都会导致泄露

基本上可以说,goroutine泄露都是因为goroutine被阻塞之后没有人唤醒它导致的

解决方法:延迟机制,超过一定时间自动关闭;确定管理好发送和接收者避免阻塞的发生

 

channel与内存逃逸

内存分配:

分配到栈上:要知道分配到哪个栈上才会分配到对应的栈上,不需要考虑GC,性能与内存友好

分配到堆上:需要考虑GC

Channel传递指针一定会逃逸因为不知道目标地址无法分配到栈上

 

Channel发送步骤

1. 看是不是 nil channel,是的话直接阻塞
2. 看有没有被阻塞的接受者,有的话直接交付数据,返回
3. 看看缓冲有没有满,没有就放缓冲,返回
4. 阻塞,等待接收者来唤醒自己
5. 被唤醒,做些清理工作

Channel接收步骤

1. 看是不是 nil channel,是的话直接阻塞
2. 看有没有被阻塞的发送者,有的话直接从发送者手里拿,返回
3. 看看缓冲有没有数据,有就读缓冲,返回
4. 阻塞,等待发送者来唤醒自己
5. 被唤醒,做些清理工作