并发send/receive 去频道

Concurrent send/receive go channel

我有一个名为 queue 的通道,假设缓冲区大小为 100。许多go例程可以向这个通道发送数据,另一个go例程坐在那里从这个通道接收数据。这是一个持久的过程,这意味着通道就像一条管道,从多端吸收数据并将数据下沉到一端。我在接收 go 例程中做了这样的事情:

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

现在我的问题是:如果在范围循环完成之前将一些新数据发送到通道缓冲区怎么办?新数据是否可用于下一个范围循环?还是这种情况下不考虑并发会漏掉?

你只需要一个 for 循环。来自 spec on range expressions:

For channels, the iteration values produced are the successive values sent on the channel until the channel is closed. If the channel is nil, the range expression blocks forever.

在这种情况下,范围循环不像一个常规范围,例如,一个切片。相反,当可以从通道读取项目时,循环体会处理它。因此,您的嵌套循环应替换为以下内容:

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

正如 所说,您只需要一个 for,因为 range 将从通道中发出值,直到它关闭。

总体而言,您描述的模式称为 fan-in. A example for a basic producer/consumer setup can be found here: 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
}