我有一个名为queue
的go频道,让我们说100作为缓冲区大小。许多go例程可以将数据发送到此通道,另一个例程就是坐在那里从该通道接收数据。这是一个持久的过程,意味着渠道的作用就像一条管道,从多个目的吸收数据,并将数据汇到一端。我在接收程序中做了类似的事情:
for {
for data := range queue {
sink(data)
}
}
现在我的问题是:如果在范围循环结束之前将一些新数据发送到通道缓冲区会怎样。新数据是否可用于下一个范围循环?如果在这种情况下不考虑并发性,他们会被遗漏?
答案 0 :(得分:5)
您只需要一个for
循环。来自spec on range expressions:
对于通道,生成的迭代值是在通道上发送的连续值,直到通道关闭。如果通道为
nil
,则范围表达式将永久阻止。
在这种情况下,范围循环不像常规范围那样作用于例如切片。相反,当可以从通道读取项目时,循环体处理它。因此,您的嵌套循环应替换为以下内容:
for data := range queue {
sink(data)
}
答案 1 :(得分:4)
正如@Tim所述,您只需要一个for
,因为range
将从通道中发出值,直到它被关闭。
总体而言,您描述的模式称为fan-in。可以在此处找到基本生产者/消费者设置的示例:http://play.golang.org/p/AhQ012Qpwj。范围循环在消费者中运行:
// consumer acts as fan in, signals when it is done.
func consumer(out chan string, done chan bool) {
for value := range out {
fmt.Println(value)
}
done <- true
}