We have already covered golang channel, buffered and unbuffered channel in detail in one of our previous articles. In this article, we will be discussing various ways to check if the golang channel buffer is full with help of practical examples.
What is a buffered channel in Go?
A buffered channel in Golang is a channel that allows a fixed length of buffer capacity so as to send and receiving of the specified data value once. Sending into buffered channel blocks when the buffer is full while receiving blocks when the buffer is empty. Goroutine can only send data to the channel when it's not full and it can receive data if it's not empty otherwise goroutine is locked to wait for sending or receiving channel.
The buffered channel can be created by passing the capacity parameter in the make
function.
ch := make(chan type, capacity)
the capacity should be greater than zero (0), to have a buffer channel.
We can declare the buffered channel as follows:-
package main
import "fmt"
func main() {
// channel of integer data type
dataChannel := make(chan int, 3)
// send data only capacity of 3 if it exceeds the capacity it will go to a deadlock
for i := 0; i < 3; i++ {
dataChannel <- i
}
// ensure channel is closed to prevent data leaks
close(dataChannel)
// print all received data into the channel
for value := range dataChannel {
fmt.Println(value)
}
}
Check the code at Golang online Playground buffered channel
Output:- For buffered channel
$ go run main.go
0
1
2
Explanation:-
In the above code, dataChannel is a buffered channel of integer data type and capacity 3. It's possible to send 3 digits into the channel without being blocked this is done by use of for loop
for i := 0; i < 3; i++ {
dataChannel <- i
}
and read the data in the channel,
for value := range dataChannel {
fmt.Println(value)
}
In Golang we can check buffered channel is full using the following:-
- Using select statement
- Using if statement
Different methods to check if golang channel buffer is Full
Method 1:-Using the if statement in Golang
We can check if the buffered channel is full without sending data by using length and capacity functions in Golang. This is possible by checking the number of content or data in a queue by using len(channelName), combined with capacity as a cap(channelName) as specified in the Golang specification context. The capacity of a slice is the number of elements for which there is space allocated in the underlying array. Read more about Golang specification length and capacity
The combination of the length and capacity of the channel will allow us to check if a channel is full without sending any data to that channel.
Example:-
package main
import "fmt"
func main() {
// channel of integer data type
dataChannel := make(chan int, 3)
// check if the channel is full
if len(dataChannel) == cap(dataChannel) {
// if channel was full
for value := range dataChannel {
fmt.Println(value)
}
}
// send data only capacity of 3 if it exceeds the capacity it will go to a deadlock
for i := 0; i < 3; i++ {
dataChannel <- i
}
// ensure channel is closed to prevent data leaks
close(dataChannel)
// print all received data into the channel
for value := range dataChannel {
fmt.Println(value)
}
}
Run the program on the playground
Output:-
$ go run main.go
0
1
2
Explanation:-
In the above program, if len(dataChannel) == cap(dataChannel) {} we are checking if the channel is full before sending data to the channel.
When the channel is full
package main
import "fmt"
func main() {
// channel of integer data type
dataChannel := make(chan int, 3)
// send data only capacity of 3 if it exceeds the capacity it will go to a deadlock
for i := 0; i < 3; i++ {
dataChannel <- i
}
// ensure the channel is closed to prevent data leaks
close(dataChannel)
// check if the channel is full
if len(dataChannel) == cap(dataChannel) {
// if the channel was full
fmt.Println("Channel is not empty")
for value := range dataChannel {
fmt.Println(value)
}
}
// print all received data into the channel
for value := range dataChannel {
fmt.Println(value)
}
}
Output:-
$ go run main.go
Channel is not empty
0
1
2
Explanation:-
In the second example, we are sending data to the channel and then checking if it's full, printing the values in the channel.
Method 2:-Using select statement in Golang
We can check if the channel is full using a select statement with a default. The default case will be used in this select statement since the select case is not possible to send data to a full channel.
Example:- Sending more data into a full channel
package main
import "fmt"
func main() {
// channel of integer data type
dataChannel := make(chan int, 3)
// send data only capacity of 3 if it exceeds the capacity it will go to a deadlock
for i := 0; i < 3; i++ {
dataChannel <- i
}
// sending data into a full channel
select {
case dataChannel <- 5:
default:
fmt.Println("channel is full")
}
close(dataChannel)
}
Output:-
$ go run main.go
channel is full
Explanation:-
In the above program, we are using a select statement to send more data into the already full channel. since the channel is blocked, the default case will display the message that the channel is full and can't receive more data unless the current queue is received.
Summary
In this article, we have discussed in length how to check if the buffer channel is full. Buffered channels are used for goroutines by sending and receiving a certain length of an element's data type for a specified capacity. This curbs the blocking of channels or communication pipelines between goroutines, by controlling when to send and receive data across the buffered channel. For programming, you will notice buffered channels are important for listening to multiple backgrounds running programs in Golang Applications. i.e blockchain emits events, in return updating the local database for various functions.
Reference