【发布时间】:2017-08-18 02:00:30
【问题描述】:
我了解通道的常规行为是在读取后清空。有没有办法在不从通道中删除值的情况下为多次读取保留一个无缓冲的通道值?
例如,我有一个 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 例程通过在使用后将数据放回通道来“回收”数据。没有一个所谓的“重复”提供了这个解决方案。这是一个示例:
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)
}
【问题讨论】:
-
无缓冲通道不保存任何值。将相同的值多次添加到缓冲通道怎么样?
-
这是一个潜在的解决方案,但正如我所提到的,我宁愿不必输入多个值。这是因为 a) 我真的不知道我需要多少。所以我必须额外抽水; b) 数据比较大,不想重复太多:(
-
听起来您只是想将通道用作围绕单个值的互斥体,为什么不直接使用互斥体呢?
-
JimB,我可以使用互斥锁/全局,但由于多个源/目标场景很难管理。
-
jfly,我查看了您的链接,但它们似乎都处理常规频道行为。在这里找不到我要找的东西:(
标签: multithreading go channel