一个发送者,N 个接收者¶
关键问题是,发送者如何知道呢?
Go 语言本身没有提供类似的函数,同时上一节,咱们也探讨了,使用 recover panic 的方式封装函数,同样会有数据竞争的问题。
语言层面不可行,那么就由开发者约定协议。
通道应当由唯一发送者关闭
若没有唯一发送者,则需要加“管理角色”的通道
第一点很好理解:当只有一个发送者时,他自己本身肯定是知道通道是否关闭,就不用再判断是否关闭了,自己想关闭就关闭,完全没事。
可要是没有唯一发送者呢?
这又要分两种情况了。
多个发送者,一个接收者
多个发送者,多个接收者
无论哪种场景,都会有数据竞争的问题。
上面我也说了,对于没有唯一发送者的方案就是加一个 “管理角色” 的通道。
为了方便解释,我将通道分为两种:
业务通道:承载数据,用于多个协程间共享数据
管理通道:仅为了标记业务通道是否关闭而存在
因此管理通道需要满足两个条件:
第一个条件:具备广播功能
那只能是无缓冲通道(关闭后,所有 read 该通道的所有协程,都能明确的知道该通道已关闭)。
当该管理通道关闭了,说明业务通道也关闭了。
当该管理通道阻塞了,说明业务通道还没关闭。
第二个条件:有唯一发送者
这个开发者非常容易实现:
对于多个发送者,一个接收者的场景,业务通道的这个接收者,就可以充当管理通道的 唯一发送者
对于多个发送者,多个接收者的场景,就需要再单独开启一个媒介协程做 唯一发送者
针对这两个场景,这边分别举个例子