In Go, do buffered channels have any order guarantee?
For example: you have two goroutines A & B that share a channel. A pushes data onto the channel while B reads from it. Are you guranted that B will read data In the same order that A put it into the channel?
I understand that if there are multiple producers or consumers the order may be non-deterministic, but I'm specifically asking about having just 1 producer and 1 consumer.
Buffered channels allows to accept a limited number of values without a corresponding receiver for those values. It is possible to create a channel with a buffe. Buffered channel are blocked only when the buffer is full. Similarly receiving from a buffered channel are blocked only when the buffer will be empty.
When a channel is created with no capacity, it is called an unbuffered channel. In turn, a channel created with capacity is called a buffered channel. To understand what the synchronization behavior will be for any goroutine interacting with a channel, we need to know the type and state of the channel.
You are calling the go routine in your code and you can't tell when the routine will end and the value will be passed to the buffered channel. As this code is asynchronous so whenever the routine will finish it will write the data to the channel and will be read on the other side.
@Tom You can actually test if len(ch) == cap(ch) { ... } where len(ch) is the number of items in the channel and cap(ch) is the capacity. However, it might be invalid by the time you enter the if block. great - now that's a complete answer!
"Are you guaranteed that B will read data In the same order that A put it into the channel?"
Yes. The order of data is guaranteed.
But the delivery is guaranteed only for unbuffered channels, not buffered.
(see second section of this answer)
You can see the idea of channels illustrated in "The Nature Of Channels In Go" from William Kennedy (Feb. 2014): it shows how the order or read/write is respected.
See also Channels:
Receivers always block until there is data to receive.
- If the channel is unbuffered, the sender blocks until the receiver has received the value.
- If the channel has a buffer, the sender blocks only until the value has been copied to the buffer; if the buffer is full, this means waiting until some receiver has retrieved a value.
Image source: Ardan labs - William Kennedy
The same William Kennedy details the Guarantee Of Delivery aspect in "The Behavior Of Channels" (Oct 2017)
Do I need a guarantee that the signal sent by a particular goroutine has been received?
Image source: Again, Ardan labs - William Kennedy
The three channel options are Unbuffered, Buffered >1 or Buffered =1.
Guarantee
- An Unbuffered channel gives you a Guarantee that a signal being sent has been received.
- Because the Receive of the signal Happens Before the Send of the signal completes.
No Guarantee
- A Buffered channel of size >1 gives you No Guarantee that a signal being sent has been received.
- Because the Send of the signal Happens Before the Receive of the signal completes.
Delayed Guarantee
- A Buffered channel of size =1 gives you a Delayed Guarantee. It can guarantee that the previous signal that was sent has been received.
- Because the Receive of the First Signal, Happens Before the Send of the Second Signal completes.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With