[Golang] Understanding Unbuffered and Buffered Channels
JackTT
Posted on September 14, 2024
Table of contents
Channel capacity
- Unbuffered channel:
- Has no capacity.
- You can imagine it like a highway that allows one car to run through but does not support any cars to park there.
- Buffered channel:
- Has a fixed capacity at declaration time.
- It's like a queue that supports holding up to a fixed number of pending messages before consuming.
Behavior
-
Unbuffered channel:
- Sender is blocked until a receiver receive the message.
- Receiver is blocked until a sender sends a message.
- The sending and receiving processes are synchronous.
-
Buffered channel:
- Senders are blocked only when the buffer is full.
- Receivers are blocked when the buffer is empty.
- The sending and receiving processes are asynchronous. Senders are released immediately after the sending action without waiting for the receiver.
Worth noting: An unbuffered channel
differs from a buffered channel with a size of 1
according to the behavior described above.
Closed channel
When a channel is closed in Go using the close()
function:
-
Sending to a closed channel causes a
panic
. - Receiving from a closed channel continues to retrieve values until the buffer is drained (for buffered channels). After the buffer is empty, further receives return the zero value of the channel's type and do not block.
You can check if a channel is closed by receiving a second value from the channel, e.g., v, ok := <-ch
. The ok
will be false
if the channel is closed.
Receive-Only & Send-only Channel
Receive-only channel in Go is a channel that can only be used to receive values.
-
Declaration:
var ch <-chan int
defines a channel from which only receiving is allowed. -
Behavior:
- Attempting to send to a read-only channel will result in a compilation error.
- Attempting to pass a receive-only channel into a function that requires normal channel also lead to a compilation error.
Send-only channel is similar.
var ch chan<- int
References
- https://go.dev/tour/concurrency/2 (By default, sends and receives block until the other side is ready. This allows goroutines to synchronize without explicit locks or condition variables)
- https://go.dev/tour/concurrency/3 (Sends to a buffered channel block only when the buffer is full. Receives block when the buffer is empty)
- https://golangr.com/channel-directions (Receive-only and Send-only channels)
- https://go101.org/article/channel.html
💖 💪 🙅 🚩
JackTT
Posted on September 14, 2024
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.