golang 单对多 channel ? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
Siril
V2EX    程序员

golang 单对多 channel ?

  •  
  • &nbs; Siril 2017-01-31 14:29:49 +08:00 6758 次点击
    这是一个创建于 3178 天前的主题,其中的信息可能已经有所发展或是发生改变。
    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
    15 条回复    2017-03-20 17:53:37 +08:00
    SuperFashi
        1
    SuperFashi  
       2017-01-31 14:55:01 +08:00 via Android
    用途?
    Valyrian
        2
    Valyrian  
       2017-01-31 14:58:43 +08:00
    以前用 golang 作业写过类似的东西。。
    Siril
        3
    Siril  
    OP
       2017-01-31 15:06:16 +08:00
    @SuperFashi
    就是一个 goroutine 从网络或者标准输入或其他地方得到了一个消息,
    需要将其发给一组 goroutine 。

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

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

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

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

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

    的确是典型的生产者 消费者问题,我一时没想起来
    SuperFashi
        13
    SuperFashi  
       2017-01-31 18:16:12 +08:00
    @Siril 啊,看懂了
    但是这种东西最好的解决办法不就是 for 一遍塞 chan 吗……
    你可以把 slice 做成线程安全,每次线程退出自己删自己就好了
    nareix
        14
    nareix  
       2017-02-01 09:37:59 +08:00
    sync.Cond
    codehz
        15
    codehz  
       2017-03-20 17:53:37 +08:00
    我记得反射就可以了。。。性能应该会比用链式结构的好吧
    `reflect.Select`可以接收一个数组
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1028 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 32ms UTC 18:40 PVG 02:40 LAX 11:40 JFK 14:40
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86