আসসালামু আলাইকুম,
আজকের পর্বে আমরা জানার চেষ্টা করব Go এর Channel সম্পর্কে, আর এটা কীভাবে কাজ করে।
Go-তে Channel কী?
Channel হলো Go-এর built-in একটা data structure,
যেটা দিয়ে goroutine গুলোর মধ্যে synchronized communication (মানে data পাঠানো আর গ্রহণ) করা যায়।
সহজ ভাষায় বললে, Channel মানে একটা pipe।
একটা goroutine data পাঠায়, আর অন্যটা সেটা receive করে।
উদাহরণ:
ch := make(chan int) // একটা int টাইপের channel তৈরি করা হলো
Channel-এর কিছু বৈশিষ্ট্য
১. Blocking Nature
Channel-এর একটা গুরুত্বপূর্ণ বৈশিষ্ট্য হলো blocking।
যদি sender বা receiver না থাকে, তাহলে যেই থাকে সে অপেক্ষা করে বসে থাকবে।
আর যেহেতু সেটা goroutine এর মধ্যে চলছে, তাই সেই goroutine-টাই block হয়ে যাবে।
sender আর receiver – দুইজনকেই একসাথে ready থাকতে হবে। না হলে communication হবে না, বরং deadlock হবে।
একটা গুরুত্বপূর্ণ বিষয়, যদি আপনে main()
function এ একটা channel তৈরি করেন এবং সেখানে কিছু ডাটা পাঠান, কিন্তু receive করার জন্য কেউ না থাকে তাহলে main()
function block হয়ে যাবে। এটাকেই Go তে deadlock বলা হয়।
২. Type Safe
Channel একবার যেই type দিয়ে বানানো হয়, সেই channel দিয়ে শুধু সেই টাইপের data-ই পাঠানো বা নেওয়া যায়।
যেমন chan int
দিয়ে শুধু int
টাইপের ভ্যালু পাঠানো যাবে।
এটা type safe system।
Channel-এর প্রকারভেদ (৩ ধরনের)
- Unbuffered Channel
- Buffered Channel
- Directional Channel
1. Unbuffered Channel
এমন একটা channel যেটাতে sender আর receiver দুইজনই একসাথে ready না হলে, যেই goroutine প্রথমে আসে সেটাই block হয়ে যায়। এই কারণে এটাকে real-time communication বলা হয়।
উদাহরণ:
ch := make(chan int) // Unbuffered channel
go func() {
ch <- 10 // sender goroutine এখানে আটকে থাকবে যতক্ষণ না main goroutine data নেয়
}()
fmt.Println(<-ch) // main goroutine data নেয়
2. Buffered Channel
এমন একটা channel, যার নিজস্ব একটি নির্দিষ্ট পরিমাণ মেমোরি (buffer) থাকে। এটি ঐ সময়ের জন্য ডেটা ধরে রাখতে পারে, যখন receiver সঙ্গে সঙ্গে ডেটা নিচ্ছে না। যতক্ষণ না buffer পূর্ণ হয়, sender ব্লক হয় না।
উদাহরণ:
ch := make(chan int, 2) // Buffered channel with size 2
ch <- 1
ch <- 2
// ch <- 3 // এখানে block হয়ে যাবে কারণ buffer পূর্ণ
fmt.Println(<-ch)
fmt.Println(<-ch)
3. Directional Channel
এমন একটা channel, যেটি কেবলমাত্র একটি নির্দিষ্ট দিক থেকে কাজ করে, হয়তো শুধু ডেটা পাঠাতে পারে (send-only) অথবা শুধু ডেটা গ্রহণ করতে পারে (receive-only)।
এই ধরনের channel ব্যবহারের মাধ্যমে ডেটা প্রবাহের দিক (direction of data flow) স্পষ্টভাবে নির্ধারণ করা যায়, যার ফলে ফাংশনের দায়িত্ব (responsibility) পরিষ্কার হয় এবং ভুল ব্যবহার বা bug হওয়ার সম্ভাবনা অনেক কমে যায়।
Directional Syntax:
টাইপ | কাজ |
---|---|
chan<- T |
শুধু পাঠানো যাবে (send-only) |
<-chan T |
শুধু নেওয়া যাবে (receive-only) |
উদাহরণ:
func sendData(ch chan<- int) {
ch <- 100 // শুধু পাঠাবে
}
func receiveData(ch <-chan int) {
fmt.Println(<-ch) // শুধু নিবে
}
func main() {
ch := make(chan int)
go sendData(ch)
receiveData(ch)
}
পরবর্তী পর্বে কী দেখব?
- কিছু channel-এর বাস্তব ব্যবহার (real usage)
- Block কোথায় হচ্ছে আর কেন হচ্ছে, সেটা কোড দেখে বুঝার চেষ্টা করব।