并发发送/接收通道

时间:2015-04-18 16:18:00

标签: concurrency go channel

我有一个名为queue的go频道,让我们说100作为缓冲区大小。许多go例程可以将数据发送到此通道,另一个例程就是坐在那里从该通道接收数据。这是一个持久的过程,意味着渠道的作用就像一条管道,从多个目的吸收数据,并将数据汇到一端。我在接收程序中做了类似的事情:

for {
    for data := range queue {
        sink(data)
    }
} 

现在我的问题是:如果在范围循环结束之前将一些新数据发送到通道缓冲区会怎样。新数据是否可用于下一个范围循环?如果在这种情况下不考虑并发性,他们会被遗漏?

2 个答案:

答案 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
}