go channel 可以保留一个值供多次读取

Can go channel keep a value for multiple reads

我了解通道的常规行为是在读取后清空。有没有办法在不从通道中删除值的情况下为多次读取保留未缓冲的通道值?

例如,我有一个 goroutine,它生成单个数据供多个下游 go 例程使用。我不想必须创建多个通道或使用缓冲通道,这将需要我复制源数据(我什至不知道我需要多少副本)。实际上,我希望能够执行以下操作:

main{
   ch := make(ch chan dType)

   ch <- sourceDataGenerator()
   for _,_ := range DynamicRange{
      go TargetGoRoutine(ch)
   }
   close(ch)       // would want this to remove the value and the channel
}
func(ch chan dType) TargetGoRoutine{
   targetCollection <- ch    // want to keep the channel value after read
}

编辑 有些人认为这是一个重复的问题。也许,但不确定。正如 n-canter 指出的那样,这里的解决方案最终看起来很简单。它所需要的只是让每个 go 例程在使用后通过将数据放回通道来 "recycle" 数据。据说 "duplicates" 的 None 提供了这个解决方案。这是一个示例:

package main
import (
  "fmt"
  "sync"
)

func main() {
 c := make(chan string)
 var wg sync.WaitGroup
    wg.Add(5)

 for i := 0; i < 5; i++ {
    go func(i int) {
        wg.Done()
        msg := <-c
        fmt.Printf("Data:%s, From go:%d\n", msg, i)
        c <-msg

    }(i)
}

   c <- "Original"
   wg.Wait()
   fmt.Println(<-c)
}

https://play.golang.org/p/EXBbf1_icG

您可以在读取后将值读回通道,但是您所有的 goroutine 将顺序读取共享值,并且您还需要一些同步原语以使最后一个 goroutine 不阻塞。

据我所知,唯一可以使用单一频道进行广播的情况是关闭它。在这种情况下,所有读者都会收到通知。

如果你不想重复大数据,也许你最好使用一些全局变量。但是要谨慎使用,因为它违反了golang规则:"Don't communicate by sharing memory; share memory by communicating."

也看看这个问题