Buffered & Unbuffered Channels in Go

List Topics
February 18, 2025
No Comments
3 min read

1️⃣ Unbuffered Channels

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:

Go
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:

Bash
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.

2️⃣ Buffered Channels

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:

Go
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:

Bash
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.

3️⃣ Buffered vs. Unbuffered: Differences

FeatureUnbuffered ChannelBuffered Channel
SynchronizationRequires receiver to be ready while sending dataCan store data even if receiver is not immediately available
Concurrency ControlDirect synchronization between sender and receiverCan handle asynchronous data exchange up to buffer capacity
Sender BlockingSender blocks if the receiver is not readySender blocks only when the buffer is full
Receiver BlockingReceiver blocks if no data is available to receiveReceiver blocks if the buffer is empty
CapacityNo buffer or capacityHas a defined capacity to store data

4️⃣ Use Cases for Buffered and Unbuffered Channels

  • Unbuffered Channels are ideal for synchronizing between goroutines where direct handoff of data is necessary.
  • Buffered Channels are useful when you need to allow some level of asynchronous data exchange, letting the sender send multiple messages without immediately needing a receiver.

Summary:

  • Unbuffered Channels facilitate synchronized communication between sender and receiver, making both wait for each other.
  • Buffered Channels allow asynchronous data exchange, where the sender can send data even if the receiver is not ready, up to a set buffer capacity.

Both types of channels are essential for managing concurrency and communication between goroutines in Go.


1️⃣ Unbuffered Channels

একটি Unbuffered Channel এর ক্ষেত্রে ডেটা পাঠানোর সময় রিসিভারকে অবশ্যই প্রস্তুত থাকতে হবে। অর্থাৎ, যখন একটি goroutine ডেটা পাঠায়, তখন আরেকটি goroutine ডেটা গ্রহণের জন্য উপস্থিত থাকতে হবে। অন্যথায়, sender goroutine ব্লক হয়ে যাবে যতক্ষণ না receiver goroutine ডেটা গ্রহণ করে।

🔹 উদাহরণ:

Go
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:

Bash
Hello from goroutine

👉 এই উদাহরণে, ডেটা পাঠানো এবং গ্রহণ সিঙ্ক্রোনাইজড ভাবে হয়, যেখানে উভয় goroutine একই সময়ে সক্রিয় থাকতে হবে।

2️⃣ Buffered Channels

একটি Buffered Channel নির্দিষ্ট পরিমাণ ডেটা ধরে রাখতে পারে, এমনকি যদি receiver goroutine তখন উপস্থিত না থাকে। Sender ডেটা পাঠাতে পারে যতক্ষণ পর্যন্ত চ্যানেলের buffer পূর্ণ না হয়। যখন buffer পূর্ণ হয়, তখন sender ব্লক হয়ে যায় এবং receiver ডেটা গ্রহণ করার পর আবার পাঠানো সম্ভব হয়।

🔹 উদাহরণ:

Go
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:

Bash
Message 1
Message 2

👉 এখানে, buffered channel দুটি মেসেজ ধারণ করতে পারে, যেটি গ্রহণ করার জন্য receiver উপস্থিত না থাকলেও কাজ করে।

3️⃣ Buffered vs. Unbuffered: পার্থক্য

বৈশিষ্ট্যUnbuffered ChannelBuffered Channel
সিঙ্ক্রোনাইজেশনডেটা পাঠানোর সময় ডেটা গ্রহণকারী goroutine উপস্থিত থাকতে হবেডেটা পাঠানোর সময় রিসিভার অনুপস্থিত থাকলেও ডেটা জমা রাখা যায়
Concurrency Controlসরাসরি concurrency synchronizationঅ্যাসিঙ্ক্রোনাইজড ভাবে কিছুটা ডেটা জমা করতে পারে
Sender Blockingরিসিভার না থাকলে sender ব্লক হয়ে যায়Channel পূর্ণ হলে sender ব্লক হবে
Receiver BlockingSender না থাকলে receiver ব্লক হয়ে যায়Channel খালি থাকলে receiver ব্লক হয়ে যায়
Capacityকোনো buffer বা capacity থাকে নানির্দিষ্ট capacity থাকে

4️⃣ Buffered এবং Unbuffered Channels-এর ব্যবহার ক্ষেত্র

  • Unbuffered Channels concurrency control এবং synchronization এর জন্য উপযুক্ত, যেখানে ডেটা তাৎক্ষণিকভাবে পাঠানো এবং গ্রহণ করা প্রয়োজন।
  • Buffered Channels ডেটা ধারণ করার প্রয়োজন থাকলে ব্যবহার করা হয়, যেখানে রিসিভার সাথে সাথে ডেটা গ্রহণ করতে না পারলেও ডেটা জমা রাখা যায়।

সারসংক্ষেপ:

  • Unbuffered Channels সিঙ্ক্রোনাইজড ডেটা আদান-প্রদানের জন্য ব্যবহৃত হয়।
  • Buffered Channels অ্যাসিঙ্ক্রোনাইজড ডেটা ধারণ এবং আদান-প্রদানের জন্য ব্যবহৃত হয়, যেখানে রিসিভার অবিলম্বে উপস্থিত থাকতে হবে না।

উভয় চ্যানেলই Go-তে concurrency এবং goroutine-এর মধ্যে যোগাযোগের জন্য গুরুত্বপূর্ণ।

©2025 Linux Bangla | Developed & Maintaind by Linux Bangla.