An Unbuffered Channel requires both the sender and receiver to be ready at the same time. This means that when one goroutine sends data through the channel, another goroutine must be available to receive it immediately. Otherwise, the sender will block until the receiver is ready.
🔹 Example:
package main
import "fmt"
func main() {
ch := make(chan string) // Unbuffered Channel
// A goroutine to send data
go func() {
ch <- "Hello from goroutine"
}()
// Receiving data
msg := <-ch
fmt.Println(msg)
}
🔹 Output:
Hello from goroutine
👉 In this example, the data transmission happens synchronously between the sender and receiver, and both goroutines must be active at the same time.
A Buffered Channel allows data to be stored in the channel even if no goroutine is immediately available to receive it. The sender can continue sending data until the buffer capacity is full, after which it will block until the receiver consumes some of the buffered data.
🔹 Example:
package main
import "fmt"
func main() {
ch := make(chan string, 2) // Buffered Channel with capacity of 2
ch <- "Message 1"
ch <- "Message 2"
// Now retrieving data from the buffered channel
fmt.Println(<-ch)
fmt.Println(<-ch)
}
🔹 Output:
Message 1
Message 2
👉 In this example, the buffered channel is able to hold two messages before any receiving goroutine is required to retrieve the data.
Feature | Unbuffered Channel | Buffered Channel |
---|---|---|
Synchronization | Requires receiver to be ready while sending data | Can store data even if receiver is not immediately available |
Concurrency Control | Direct synchronization between sender and receiver | Can handle asynchronous data exchange up to buffer capacity |
Sender Blocking | Sender blocks if the receiver is not ready | Sender blocks only when the buffer is full |
Receiver Blocking | Receiver blocks if no data is available to receive | Receiver blocks if the buffer is empty |
Capacity | No buffer or capacity | Has a defined capacity to store data |
Both types of channels are essential for managing concurrency and communication between goroutines in Go.
একটি Unbuffered Channel এর ক্ষেত্রে ডেটা পাঠানোর সময় রিসিভারকে অবশ্যই প্রস্তুত থাকতে হবে। অর্থাৎ, যখন একটি goroutine ডেটা পাঠায়, তখন আরেকটি goroutine ডেটা গ্রহণের জন্য উপস্থিত থাকতে হবে। অন্যথায়, sender goroutine ব্লক হয়ে যাবে যতক্ষণ না receiver goroutine ডেটা গ্রহণ করে।
🔹 উদাহরণ:
package main
import "fmt"
func main() {
ch := make(chan string) // Unbuffered Channel
// একটি goroutine ডেটা পাঠানোর জন্য
go func() {
ch <- "Hello from goroutine"
}()
// ডেটা গ্রহণ করা হচ্ছে
msg := <-ch
fmt.Println(msg)
}
🔹 Output:
Hello from goroutine
👉 এই উদাহরণে, ডেটা পাঠানো এবং গ্রহণ সিঙ্ক্রোনাইজড ভাবে হয়, যেখানে উভয় goroutine একই সময়ে সক্রিয় থাকতে হবে।
একটি Buffered Channel নির্দিষ্ট পরিমাণ ডেটা ধরে রাখতে পারে, এমনকি যদি receiver goroutine তখন উপস্থিত না থাকে। Sender ডেটা পাঠাতে পারে যতক্ষণ পর্যন্ত চ্যানেলের buffer পূর্ণ না হয়। যখন buffer পূর্ণ হয়, তখন sender ব্লক হয়ে যায় এবং receiver ডেটা গ্রহণ করার পর আবার পাঠানো সম্ভব হয়।
🔹 উদাহরণ:
package main
import "fmt"
func main() {
ch := make(chan string, 2) // Buffered Channel যার capacity 2
ch <- "Message 1"
ch <- "Message 2"
// এখন buffered channel থেকে ডেটা নেওয়া হচ্ছে
fmt.Println(<-ch)
fmt.Println(<-ch)
}
🔹 Output:
Message 1
Message 2
👉 এখানে, buffered channel দুটি মেসেজ ধারণ করতে পারে, যেটি গ্রহণ করার জন্য receiver উপস্থিত না থাকলেও কাজ করে।
বৈশিষ্ট্য | Unbuffered Channel | Buffered Channel |
---|---|---|
সিঙ্ক্রোনাইজেশন | ডেটা পাঠানোর সময় ডেটা গ্রহণকারী goroutine উপস্থিত থাকতে হবে | ডেটা পাঠানোর সময় রিসিভার অনুপস্থিত থাকলেও ডেটা জমা রাখা যায় |
Concurrency Control | সরাসরি concurrency synchronization | অ্যাসিঙ্ক্রোনাইজড ভাবে কিছুটা ডেটা জমা করতে পারে |
Sender Blocking | রিসিভার না থাকলে sender ব্লক হয়ে যায় | Channel পূর্ণ হলে sender ব্লক হবে |
Receiver Blocking | Sender না থাকলে receiver ব্লক হয়ে যায় | Channel খালি থাকলে receiver ব্লক হয়ে যায় |
Capacity | কোনো buffer বা capacity থাকে না | নির্দিষ্ট capacity থাকে |
উভয় চ্যানেলই Go-তে concurrency এবং goroutine-এর মধ্যে যোগাযোগের জন্য গুরুত্বপূর্ণ।