【问题标题】:Data duplication by multiple goroutines多个 goroutine 的数据重复
【发布时间】:2021-01-21 17:45:01
【问题描述】:

我正在学习 goroutine 和通道,并且想知道如果多个 goroutine 尝试从同一个通道获取数据会发生什么。

go 运行时如何确保通道中被多个 goroutine 读取的数据仅提供给在通道上等待的一个 goroutine,而不是复制或发送到多个 goroutine。

当有多个 goroutine 试图从完全相同的通道中获取数据时,go 运行时是否会阻止竞争条件?对于哪些等待的 goroutine 获得数据,例如先来先服务,是否存在某种排序?

【问题讨论】:

  • 永远不可能从一个通道中多次读取一个值(即使是多个 goroutines 也不行)。通道/运行时本身可以确保这一点。如何?为此,您必须深入研究 Go 中的实现方式。
  • 感谢大家的意见。我真的很想知道使用哪种并发模型(使用锁或 CSP 同步)来防止从同一通道获取数据的多个 goroutine 的竞争条件。
  • @VipulKumar,CSP 是一个比用于实现它的概念更高级别的概念。 go memory 模型精确地描述了期望,但是 source 是 memory 模型如何实现的唯一参考。

标签: go concurrency


【解决方案1】:

Channel 是 goroutine 相互同步的主要方式之一。因此,它们包含一种机制,以确保一次只有一个 goroutine 能够从通道中提取数据项,并且检索到的数据项不会重复。

您不能真正指望多个 goroutine 从同一通道成功读取的任何特定序列,因为特定 goroutine 的读取将完成取决于所使用的多线程算法。

查看此讨论,Goroutines are cooperatively scheduled. Does that mean that goroutines that don't yield execution will cause goroutines to run one by one?

您可以依赖多个 goroutine 是否从同一个通道读取数据。然后当通道中有数据要读取时,其中一个 goroutine 将成功读取,并且读取的数据不会被任何其他等待从通道读取成功的 goroutine 读取。

请参阅 Concurrency from golang-book.com,其中解释了并发、goroutine 和通道。

也请参阅How to use channels to safely synchronise data in Go

另请参阅此答案,该答案描述了使用通道而不是诸如互斥锁之类的同步原语来维护侦听器的动态列表:https://stackoverflow.com/a/18897083/1466970

另请参阅对Anatomy of Channels in Go - Concurrency in Go 的冗长且有些令人筋疲力尽的描述。

【讨论】:

    【解决方案2】:

    这里有一个很好的 Go 通道内部分析 https://codeburst.io/diving-deep-into-the-golang-channels-549fd4ed21a8
    基本上,通道维护一个等待读取操作的 goroutines 的内部队列。当发送某些东西时,它只是从该队列中选择一个 goroutine 并为其提供数据。如果没有人在等待 - 数据进入缓冲区或阻塞写入器。

    【讨论】:

      猜你喜欢
      • 2021-08-15
      • 2019-02-01
      • 2017-07-19
      • 2020-04-03
      • 2018-02-05
      • 2020-08-02
      • 1970-01-01
      • 2018-04-05
      • 1970-01-01
      相关资源
      最近更新 更多