原文作者:大道至简
分布模式
分布模式将从输入channel中读取的值往输出channel中的其中一个发送。
Goroutine方式
roundrobin的方式选择输出channel。
Reflect方式
利用发射随机的选择。
eapache
eapache/channels提供了一些channel应用模式的方法,比如上面的扇入扇出模式等。
因为go本身的channel无法再进行扩展,库定义了自己的channel接口,并提供了与channel方便的转换。
提供了四个方法:
Distribute: 从输入channel读取值,发送到其中一个输出channel中。当输入channel关闭后,输出channel都被关闭
Tee: 从输入channel读取值,发送到所有的输出channel中。当输入channel关闭后,输出channel都被关闭
Multiplex: 合并输入channel为一个输出channel, 当所有的输入都关闭后,输出才关闭
Pipe: 将两个channel串起来
同时对上面的四个函数还提供了的函数,输入关闭后不会关闭输出。
下面看看对应的函数的例子。
Distribute
Tee
Multiplex
Pipe
集合操作
从channel的行为来看,它看起来很像一个数据流,所以我们可以实现一些类似Scala 集合的操作。
Scala的集合类提供了丰富的操作(方法), 当然其它的一些编程语言或者框架也提供了类似的方法, 比如Apache Spark、Java Stream、ReactiveX等。
下面列出了一些方法的实现,我相信经过一些人的挖掘,相关的方法可以变成一个很好的类库,但是目前我们先看一些例子。
skip
skip函数是从一个channel中跳过开一些数据,然后才开始读取。
skipN
skipN跳过开始的N个数据。
skipFn
skipFn 提供Fn函数为true的数据,比如跳过偶数。
skipWhile
跳过开头函数fn为true的数据。
take
skip的反向操作,读取一部分数据。
takeN
takeN 读取开头N个数据。
takeFn
takeFn 只筛选满足fn的数据。
takeWhile
takeWhile只挑选开头满足fn的数据。
flat
平展(flat)操作是一个有趣的操作。
如果输入是一个channel,channel中的数据还是相同类型的channel, 那么flat将返回一个输出channel,输出channel中的数据是输入的各个channel中的数据。
它与扇入不同,扇入的输入channel在调用的时候就是固定的,并且以数组的方式提供,而flat的输入是一个channel,可以运行时随时的加入channel。
map
map和reduce是一组常用的操作。
map将一个channel映射成另外一个channel, channel的类型可以不同。
因为是go的关键字,所以我们不能命名函数类型为,这里用代替。
比如你可以处理一个公司员工工资的channel, 输出一个扣税之后的员工工资的channel。
reduce
总结
本文列出了channel的一些深入应用的模式,相信通过阅读本文,你可以更加深入的了解Go的channel类型,并在开发中灵活的应用channel。也欢迎你在评论中提出更多的 channel的应用模式。
所有的代码可以在github上找到:smallnest/channels。
参考资料
https://github.com/kat-co/concurrency-in-go-src
https://github.com/campoy/justforfunc/tree/master/27-merging-chans
https://github.com/eapache/channels
https://github.com/LK4D4/trylock
https://stackoverflow.com/questions/36391421/explain-dont-communicate-by-sharing-memory-share-memory-by-communicating
https://github.com/lrita/gosync
https://www.ardanlabs.com/blog/2017/10/the-behavior-of-channels.html
版权申明:内容来源网络,版权归原创者所有。除非无法确认,我们都会标明作者及出处,如有侵权烦请告知,我们会立即删除并表示歉意。谢谢。
Golang语言社区
游戏服务器架构丨分布式技术丨大数据丨游戏算法学习
领取专属 10元无门槛券
私享最新 技术干货