【发布时间】:2014-11-05 20:32:56
【问题描述】:
在 Go 中,缓冲通道有顺序保证吗?
例如: 你有两个 goroutine A & B 共享一个通道。 A 将数据推送到通道上,而 B 从通道中读取数据。是否保证 B 会按照 A 放入通道的顺序读取数据?
我知道,如果有多个生产者或消费者,订单可能是不确定的,但我特意询问只有 1 个生产者和 1 个消费者。
【问题讨论】:
在 Go 中,缓冲通道有顺序保证吗?
例如: 你有两个 goroutine A & B 共享一个通道。 A 将数据推送到通道上,而 B 从通道中读取数据。是否保证 B 会按照 A 放入通道的顺序读取数据?
我知道,如果有多个生产者或消费者,订单可能是不确定的,但我特意询问只有 1 个生产者和 1 个消费者。
【问题讨论】:
“你保证B会按照A放入通道的顺序读取数据吗?”
是的。保证数据的顺序。
但交付只保证无缓冲通道,不缓冲。
(请参阅此答案的第二部分)
您可以在 William Kennedy(2014 年 2 月)的“The Nature Of Channels In Go”中看到通道的概念:它显示了如何尊重顺序或读/写。
另见Channels:
接收器总是阻塞,直到有数据接收。
- 如果通道没有缓冲,发送方会阻塞,直到接收方收到该值。
- 如果通道有缓冲区,发送方只会阻塞,直到值被复制到缓冲区;如果缓冲区已满,这意味着等待某个接收器检索到一个值。
图片来源:Ardan labs - William Kennedy
William Kennedy 在“The Behavior Of Channels”(2017 年 10 月)
中详细介绍了交付保证方面我是否需要保证特定 goroutine 发送的信号已被接收?
图片来源:Ardan labs - William Kennedy
三个通道选项是 Unbuffered、Buffered >1 或 Buffered =1。
保证
- 无缓冲通道为您提供保证发送的信号已收到。
- 因为信号的接收发生在信号的发送完成之前。
无保证
- 大小>1的缓冲通道不保证发送的信号已被接收。
- 因为信号的发送发生在信号的接收完成之前。
延迟保证
- size =1 的缓冲渠道为您提供延迟保证。它可以保证之前发送的信号已经被接收到。
- 因为第一个信号的接收发生在第二个信号的发送之前完成。
【讨论】: