gpt4 book ai didi

go - 如何实现一个channel和多个reader同时读取相同的数据?

转载 作者:行者123 更新时间:2023-12-01 22:10:37 24 4
gpt4 key购买 nike

我需要几个函数具有相同的 channel 作为参数并同时获取相同的数据。
这些函数中的每一个都具有彼此独立的任务,但它们从相同的值开始。
例如,给定一个整数 slice ,一个函数计算其值的总和,另一个函数同时计算平均值。它们将是 goroutines。
一种解决方案是从一个值创建多个 channel ,但我想避免这种情况。我可能必须添加或删除功能,为此,我必须添加或删除 channel 。
我想我知道扇出模式可能是一种选择,但我不太了解它的实现。

最佳答案

问题是针对 the rules of SO ——因为它没有提出任何需要帮助的具体问题,而是要求进行辅导。
无论如何,有两个需要进一步研究的指针:基本上——考虑到每个接收消耗一个发送给它的值的 channel 属性,因此不可能多次读取一次发送的值——这样的问题有两种解决方法。
第一种方法,也就是所谓的“扇出”,是让所有消费者都有一个“个人”专用 channel ,复制要广播的值与消费者的数量一样多,并将每个副本发送给每个消费者专用 channel 。
表面上最自然的实现方式是有一个单一的 channel ,生产者将其工作单元发送到该 channel ——而不关心消费者有多少阅读它们——然后有一个专用的 goroutine 接收这些工作单元,复制它们中的每一个并将副本发送到消费者的专用 channel 。
第二种方法是使用 sync 中的内容降低级别并实现基本相同的方案。包裹。
可以想到以下方案:

  • 有定制struct具有 sync.Mutex 的类型保护类型的状态。
  • 有一个字段可以保存多个消费者必须读取的值。
  • 有一个那种类型的柜台。
  • 有一个sync.Cond在那种类型中也是如此。
  • 也有一个容量为 1 的 channel 。

  • 向消费者传达新的值(value)如下所示:
  • 锁定互斥锁。
  • 验证计数器为 0,否则 panic 。
  • 将新值写入相应的字段。
  • 将计数器设置为消费者数量。
  • 解锁互斥锁。
  • 脉冲sync.Cond .

  • 消费者应该在 sync.Cond 的等待调用中 sleep 。 .
    一旦发送者发出脉冲,运行消费者代码的 goroutines 就会被唤醒并尝试读取该值。
    读取值滚动如下:
  • 锁定互斥锁。
  • 验证计数器大于零,否则 panic 。
  • 读取值。
  • 将计数器减一。
  • 如果计数器变为 0,则在该特殊 channel 上发送。
  • 解锁互斥锁。

  • 需要该 channel 与发送方沟通所有消费者都已完成读取:在尝试发送消费者必须从该 channel 读取的新值之前。
    正如您可能看到的那样,第二种方法涉及更多且难以正确处理,因此我建议使用第一种方法。

    我还要注意,您似乎缺乏有关如何实现并发运行和通信任务的某些背景知识。
    我在此推荐阅读 The Book以及至少 The Blog 的这些章节:
  • Go Concurrency Patterns: Pipelines and cancellation .
  • Go Concurrency Patterns: Timing out, moving on
  • Advanced Go Concurrency Patterns
  • 关于go - 如何实现一个channel和多个reader同时读取相同的数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63971788/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com