In Go, channels are a way for goroutines to communicate with each other. They provide a mechanism to send and receive data between goroutines in a safe and synchronized manner. Channels help avoid race conditions by allowing goroutines to pass data directly.
Here’s a detailed explanation of channels with examples.
You can create a channel using the make
function. Channels have a type, which determines the type of data they can carry.
🔹 Example:
package main
import "fmt"
func main() {
// Create a channel of type string
ch := make(chan string)
// Start a goroutine to send data to the channel
go func() {
ch <- "Hello from the channel!"
}()
// Receive the data from the channel
msg := <-ch
fmt.Println(msg)
}
🔹 Output:
Hello from the channel!
👉 In this example, a goroutine sends the string "Hello from the channel!"
into the channel ch
, and the main function receives it.
A buffered channel allows you to send multiple values without a corresponding receiver immediately being ready. The size of the buffer determines how many values can be stored in the channel.
🔹 Example:
package main
import "fmt"
func main() {
// Create a buffered channel with a capacity of 2
ch := make(chan string, 2)
// Sending values into the buffered channel
ch <- "Message 1"
ch <- "Message 2"
// Receiving values from the channel
fmt.Println(<-ch)
fmt.Println(<-ch)
}
🔹 Output:
Message 1
Message 2
👉 Here, the buffered channel ch
can store two messages before requiring a receiver to read them.
You can specify the direction of data flow in a channel—either send-only or receive-only. This helps enforce correct usage in function parameters and return types.
🔹 Example:
package main
import "fmt"
// Function that only sends data to a channel
func sendMessage(ch chan<- string, msg string) {
ch <- msg
}
// Function that only receives data from a channel
func receiveMessage(ch <-chan string) {
fmt.Println(<-ch)
}
func main() {
ch := make(chan string)
go sendMessage(ch, "Hello, Channel Direction!")
receiveMessage(ch)
}
🔹 Output:
Hello, Channel Direction!
👉 The sendMessage
function is restricted to sending data, while receiveMessage
is restricted to receiving data from the channel.
When you’re done sending data into a channel, you can close it using the close
function. Once closed, no more data can be sent to the channel.
🔹 Example:
package main
import "fmt"
func main() {
ch := make(chan int)
go func() {
for i := 1; i <= 5; i++ {
ch <- i
}
close(ch) // Close the channel
}()
// Range over the channel until it's closed
for val := range ch {
fmt.Println(val)
}
}
🔹 Output:
1
2
3
4
5
👉 After sending 5 values, the channel is closed. The for
loop iterates over the channel until it's closed.
The select
statement is used to handle multiple channels concurrently. It waits for one of the multiple channel operations to proceed.
🔹 Example:
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
time.Sleep(1 * time.Second)
ch1 <- "Message from ch1"
}()
go func() {
time.Sleep(2 * time.Second)
ch2 <- "Message from ch2"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-ch1:
fmt.Println(msg1)
case msg2 := <-ch2:
fmt.Println(msg2)
}
}
}
🔹 Output:
Message from ch1
Message from ch2
👉 The select
statement waits for messages from either ch1
or ch2
. Whichever channel sends data first is handled.
Channels are often used to synchronize goroutines, ensuring that one goroutine waits for another to complete.
🔹 Example:
package main
import "fmt"
func worker(done chan bool) {
fmt.Println("Working...")
done <- true // Signal that the work is done
}
func main() {
done := make(chan bool)
go worker(done)
<-done // Wait for the worker to finish
fmt.Println("Worker done!")
}
🔹 Output:
Working...
Worker done!
👉 Here, the main function waits for the worker goroutine to finish by receiving a value from the done
channel.
select
statement allows you to work with multiple channels concurrently.Channels are a key part of Go's concurrency model, allowing efficient and safe communication between goroutines.
Go প্রোগ্রামিং ভাষায় Channels একটি উপায় যেখানে goroutine-এর মধ্যে ডেটা আদান-প্রদান করা যায়। Channels ব্যবহার করে দুটি goroutine নিরাপদ ও সিঙ্ক্রোনাইজড উপায়ে ডেটা পাঠাতে ও গ্রহণ করতে পারে। Channels এর মাধ্যমে race conditions এড়ানো যায় কারণ এটি সরাসরি ডেটা পাস করতে সাহায্য করে।
এখানে Channels নিয়ে বিস্তারিত ব্যাখ্যা এবং কিছু উদাহরণ দেওয়া হলো।
Channel তৈরি করতে make
ফাংশন ব্যবহার করা হয়। Channel-এর একটি টাইপ থাকে, যা নির্ধারণ করে Channel-এর মধ্যে কোন ধরনের ডেটা পাঠানো যাবে।
🔹 উদাহরণ:
package main
import "fmt"
func main() {
// একটি string টাইপ Channel তৈরি করা হলো
ch := make(chan string)
// একটি goroutine শুরু করা হলো, যেটি Channel-এ ডেটা পাঠাবে
go func() {
ch <- "Hello from the channel!"
}()
// Channel থেকে ডেটা গ্রহণ করা হলো
msg := <-ch
fmt.Println(msg)
}
🔹 আউটপুট:
Hello from the channel!
👉 এই উদাহরণে, একটি goroutine Channel-এ "Hello from the channel!"
পাঠাচ্ছে, এবং main ফাংশন সেই ডেটা গ্রহণ করছে।
একটি Buffered Channel আপনাকে একাধিক মান পাঠাতে দেয়, যখন কোনো রিসিভার তা গ্রহণের জন্য সরাসরি প্রস্তুত থাকে না। Buffer-এর সাইজ নির্ধারণ করে কতগুলো মান Channel-এ জমা হতে পারবে।
🔹 উদাহরণ:
package main
import "fmt"
func main() {
// একটি buffered channel তৈরি করা হলো যার capacity ২
ch := make(chan string, 2)
// Channel-এ মান পাঠানো হচ্ছে
ch <- "Message 1"
ch <- "Message 2"
// Channel থেকে মান গ্রহণ করা হচ্ছে
fmt.Println(<-ch)
fmt.Println(<-ch)
}
🔹 আউটপুট:
Message 1
Message 2
👉 এই উদাহরণে, buffered channel ch
২টি মেসেজ ধরে রাখতে পারে, রিসিভার ডেটা পড়ার আগেই।
Channel-এর ডেটা প্রবাহের দিক নির্দেশ করা যায়— হয় send-only (শুধু পাঠানো যাবে) অথবা receive-only (শুধু গ্রহণ করা যাবে)। এটি ফাংশনের প্যারামিটার ও রিটার্ন টাইপে সঠিক ব্যবহার নিশ্চিত করতে সাহায্য করে।
🔹 উদাহরণ:
package main
import "fmt"
// শুধুমাত্র ডেটা পাঠানোর ফাংশন
func sendMessage(ch chan<- string, msg string) {
ch <- msg
}
// শুধুমাত্র ডেটা গ্রহণ করার ফাংশন
func receiveMessage(ch <-chan string) {
fmt.Println(<-ch)
}
func main() {
ch := make(chan string)
go sendMessage(ch, "Hello, Channel Direction!")
receiveMessage(ch)
}
🔹 আউটপুট:
Hello, Channel Direction!
👉 sendMessage
ফাংশন শুধুমাত্র ডেটা পাঠানোর জন্য, আর receiveMessage
ফাংশন শুধুমাত্র ডেটা গ্রহণ করার জন্য ব্যবহৃত হচ্ছে।
ডেটা পাঠানো শেষ হলে, close
ফাংশন ব্যবহার করে Channel বন্ধ করা যায়। Channel বন্ধ হলে, আর কোনো ডেটা পাঠানো সম্ভব নয়।
🔹 উদাহরণ:
package main
import "fmt"
func main() {
ch := make(chan int)
go func() {
for i := 1; i <= 5; i++ {
ch <- i
}
close(ch) // Channel বন্ধ করা হলো
}()
// Channel এর ওপর `range` করে ডেটা পড়া হচ্ছে যতক্ষণ না এটি বন্ধ হয়
for val := range ch {
fmt.Println(val)
}
}
🔹 আউটপুট:
1
2
3
4
5
👉 ৫টি মান পাঠানোর পরে, Channel বন্ধ করা হয়। for
লুপ Channel এর উপর iterate করে যতক্ষণ তা বন্ধ না হয়।
select
স্টেটমেন্টটি একাধিক Channel-এর সাথে একযোগে কাজ করার জন্য ব্যবহৃত হয়। এটি একাধিক Channel অপারেশন থেকে যেকোনো একটির জন্য অপেক্ষা করে।
🔹 উদাহরণ:
package main
import (
"fmt"
"time"
)
func main() {
ch1 := make(chan string)
ch2 := make(chan string)
go func() {
time.Sleep(1 * time.Second)
ch1 <- "Message from ch1"
}()
go func() {
time.Sleep(2 * time.Second)
ch2 <- "Message from ch2"
}()
for i := 0; i < 2; i++ {
select {
case msg1 := <-ch1:
fmt.Println(msg1)
case msg2 := <-ch2:
fmt.Println(msg2)
}
}
}
🔹 আউটপুট:
Message from ch1
Message from ch2
👉 select
স্টেটমেন্টটি অপেক্ষা করে ch1
অথবা ch2
থেকে ডেটা আসার জন্য এবং যেটি আগে আসে সেটিকে প্রসেস করে।
Channels প্রায়ই goroutine-এর মধ্যে Synchronization করার জন্য ব্যবহৃত হয়, যার মাধ্যমে একটি goroutine আরেকটি goroutine-এর কাজ শেষ হওয়ার জন্য অপেক্ষা করতে পারে।
🔹 উদাহরণ:
package main
import "fmt"
func worker(done chan bool) {
fmt.Println("Working...")
done <- true // সিগন্যাল দিচ্ছে যে কাজ শেষ
}
func main() {
done := make(chan bool)
go worker(done)
<-done // worker goroutine-এর কাজ শেষ হওয়া পর্যন্ত অপেক্ষা করছে
fmt.Println("Worker done!")
}
🔹 আউটপুট:
Working...
Worker done!
👉 এখানে main ফাংশন worker goroutine-এর কাজ শেষ হওয়া পর্যন্ত অপেক্ষা করে, done Channel থেকে ডেটা গ্রহণ করার মাধ্যমে।
close
ফাংশন দিয়ে, এবং পরে আর কোনো ডেটা পাঠানো যাবে না।select
স্টেটমেন্ট একাধিক Channel-এর মধ্যে একযোগে কাজ করতে দেয়।Channels Go-এর concurrency মডেলের একটি গুরুত্বপূর্ণ অংশ, যা goroutine-এর মধ্যে নিরাপদ এবং কার্যকরী যোগাযোগ নিশ্চিত করে।