golang 单对多 channel ?

2017-01-31 14:29:49 +08:00
 Siril
golang 这里有人用吗

居然没有内置这种功能。。。
想到个办法,在此抛砖引玉

刚试着弄了个,思路是制造一个链式的结构,
链上的每个元素对应一个 goroutine ,这个 goroutine
读取上一个节点发过来的数据扔到输出 channel 上,并转发给下一个。
输出 channel 阻塞就退出自己。(所以发送必须比接收慢)
而且链上有多少个节点,相当于多少容量的 buffer ,
无法确认消息送达到全部 channel

type chaincast struct {
v interface{} //message payload.
out chan interface{} //message output channel
spawn chan<- chaincast //send to this channel to spawn goroutine for chain element.
next chan chaincast //channel for passing message to next
prev chan chaincast //channel for receiving message from prev
}
代码在这,可能有大 bug :
https://play.golang.org/p/6D9wZ9Qnp8
6328 次点击
所在节点    程序员
15 条回复
SuperFashi
2017-01-31 14:55:01 +08:00
用途?
Valyrian
2017-01-31 14:58:43 +08:00
以前用 golang 作业写过类似的东西。。
Siril
2017-01-31 15:06:16 +08:00
@SuperFashi
就是一个 goroutine 从网络或者标准输入或其他地方得到了一个消息,
需要将其发给一组 goroutine 。

这场景应该是比较常见吧。
ovear
2017-01-31 15:09:53 +08:00
这个不是直接封装 chan 就好了么
一个分发 chan ,一个 slice ,多个处理 chan
分发 chan 里面直接循环往 slice 的 chan 塞东西就好了。。有啥问题么?
jarlyyn
2017-01-31 15:14:02 +08:00
没看懂用途
jarlyyn
2017-01-31 15:16:20 +08:00
@Siril

按你 3 楼的描述,觉得起个 go 专门塞 Chan

然后多个 go 取 Chan 的问题么
buckethead1
2017-01-31 15:30:30 +08:00
就是 pub/sub 么...
Siril
2017-01-31 15:49:45 +08:00
@jarlyyn

对,就是一个 go routine 负责从外部读取一些东西塞 chan ,
其他一组 go routine 需要取 chan ,
这组 go routine 随时有新增和退出。

如果不用 mutex 。。。
lecher
2017-01-31 15:53:17 +08:00
生产者和消费者模型,七牛的公开技术文档经常提到这个设计模式在内部项目的应用场景。
wweir
2017-01-31 15:59:47 +08:00
chan 的 close 信号是广播的
Siril
2017-01-31 17:15:11 +08:00
@ovear 我似乎理解你说的意思,就是元素为 chan 的 slice 。
一开始就是这么弄的, 然后发现 2 个问题:
新开的 goroutine 需要获取一个 chan 用来收消息;
一个收消息的 goroutine 可能随时退出,然后这个 slice 大小只增不减。
ovear
2017-01-31 17:22:53 +08:00
@Siril 这个问题很好解决啊
在分发线程检测是否有无效 chan ,有的话从 slice 中删除就好了

的确是典型的生产者 消费者问题,我一时没想起来
SuperFashi
2017-01-31 18:16:12 +08:00
@Siril 啊,看懂了
但是这种东西最好的解决办法不就是 for 一遍塞 chan 吗……
你可以把 slice 做成线程安全,每次线程退出自己删自己就好了
nareix
2017-02-01 09:37:59 +08:00
sync.Cond
codehz
2017-03-20 17:53:37 +08:00
我记得反射就可以了。。。性能应该会比用链式结构的好吧
`reflect.Select`可以接收一个数组

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/337503

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX