• 请不要在回答技术问题时复制粘贴 AI 生成的内容
Siril
V2EX  ›  程序员

golang 单对多 channel ?

  •  
  •   Siril · Jan 31, 2017 · 7656 views
    This topic created in 3567 days ago, the information mentioned may be changed or developed.
    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 replies  •  2017-03-20 17:53:37 +08:00
    SuperFashi
    SuperFashi
    Jan 31, 2017 via Android
    1
    用途?
    Valyrian
    Valyrian
    Jan 31, 2017
    2
    以前用 golang 作业写过类似的东西。。
    Siril
    Siril
    OP
    Jan 31, 2017
    3
    @SuperFashi
    就是一个 goroutine 从网络或者标准输入或其他地方得到了一个消息,
    需要将其发给一组 goroutine 。

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

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

    然后多个 go 取 Chan 的问题么
    buckethead1
    buckethead1
    Jan 31, 2017
    7
    就是 pub/sub 么...
    Siril
    Siril
    OP
    Jan 31, 2017
    8
    @jarlyyn

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

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

    的确是典型的生产者 消费者问题,我一时没想起来
    SuperFashi
    SuperFashi
    Jan 31, 2017
    13
    @Siril 啊,看懂了
    但是这种东西最好的解决办法不就是 for 一遍塞 chan 吗……
    你可以把 slice 做成线程安全,每次线程退出自己删自己就好了
    nareix
    nareix
    Feb 1, 2017
    14
    sync.Cond
    codehz
    codehz
    Mar 20, 2017
    15
    我记得反射就可以了。。。性能应该会比用链式结构的好吧
    `reflect.Select`可以接收一个数组
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Privacy   ·   Solana   ·   675 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 39ms · UTC 21:17 · PVG 05:17 · LAX 13:17 · JFK 16:17
    ♥ Do have faith in what you're doing.