মডিউল পাঠ (1/5)
Goroutines: লাইটওয়েট সমান্তরালতা
একটি গোরুটিন হল Go দ্বারা পরিচালিত সমসাময়িক সম্পাদনের একটি ইউনিট
রানটাইম আপনি একটি ফাংশনের সামনে go কীওয়ার্ড দিয়ে একটি চালু করুন৷
কল:
go greet("Anna") // chiamata a funzione esistente
go func() { // funzione anonima
fmt.Println("hi")
}()go বিবৃতিটি অবিলম্বে ফিরে আসে: গোরুটিন শুরু হয়
সমান্তরাল এবং কলার চলতে থাকে।
কেন তারা "হালকা"
- প্রাথমিক স্ট্যাক ~2KB (গতিশীলভাবে বৃদ্ধি পায়, প্রয়োজনে শত শত এমবি পর্যন্ত)।
- রানটাইম (
GOMAXPROCS) দ্বারা অল্প সংখ্যক OS থ্রেডে মাল্টিপ্লেক্সড। - হাজার হাজার/মিলিয়ন গোরুটিন রুটিন; OS থ্রেডের সাথে তারা অসম্ভব হবে।
ধারণাগতভাবে এটি "সমসাময়িক অগ্নি-এবং-ভুলে", কিন্তু সব সঙ্গে
সমন্বয় করার জন্য বাহাদুরী সরঞ্জাম (চ্যানেল, sync.WaitGroup,
context)।
প্রধান অপেক্ষা করে না
func main() {
go func() { fmt.Println("ciao dalla goroutine") }()
// main esce subito: niente garanzia che la goroutine completi
}যখন main ফিরে আসে, প্রক্রিয়াটি শেষ হয়ে যায়: গোরুটিন পাওয়া যায় না
"তাদের কাজ শেষ করার জন্য", তাদের সাথে একসাথে হত্যা করা হয়
প্রক্রিয়া স্পষ্ট সিঙ্ক্রোনাইজেশন প্রয়োজন.
সিঙ্ক্রোনাইজেশন: একটি পূর্বরূপ
তিনটি টুল যা আপনি পরবর্তী পাঠে দেখতে পাবেন:
// 1) Channel: la goroutine "segnala" via canale
done := make(chan struct{})
go func() {
work()
done <- struct{}{}
}()
<-done // attendi
// 2) sync.WaitGroup: N goroutine
var wg sync.WaitGroup
wg.Add(1)
go func() { defer wg.Done(); work() }()
wg.Wait()
// 3) context: cancellazione/timeout propagati"ক্লাসিক" ক্লোজার-ইন-লুপ বাগ
Go 1.21 পর্যন্ত এটি একটি ঘন ঘন গোটচা ছিল:
for i := 0; i < 3; i++ {
go func() { fmt.Println(i) }() // stampa "3 3 3" su versioni vecchie
}Go 1.22 থেকে for ভেরিয়েবলটি নতুনভাবে প্রতিটিতে তৈরি করা হয়েছে
পুনরাবৃত্তি, তাই বাগটি ডিফল্টরূপে সংশোধন করা হয়। পুরানো কোডবেসে আপনি হবে
এখনও ফিক্স প্যাটার্ন দেখুন:
for i := 0; i < 3; i++ {
i := i // shadow esplicito
go func() { fmt.Println(i) }()
}
// oppure passa come argomento:
for i := 0; i < 3; i++ {
go func(n int) { fmt.Println(n) }(i)
}গোরুটিন!= OS থ্রেড
| দৃষ্টিভঙ্গি | গোরুটিন | OS থ্রেড |
|---|---|---|
| প্রাথমিক স্ট্যাক | ~2 KB | 1–8 MB (শুরুতে বরাদ্দ) |
| সৃষ্টি | ন্যানোসেকেন্ড | মাইক্রোসেকেন্ড |
| সময়সূচী | রানটাইম যান (সমবায়) | কার্নেল (আগে) |
| ব্যবহারিক গণনা | 100K+ | কয়েক হাজার |
একটি একক ওএস থ্রেড অনেকগুলি গোরুটিন হোস্ট করতে পারে। রানটাইম চলে যখন প্রয়োজন হয় থ্রেড জুড়ে goroutines.
চেষ্টা করে দেখুন
একটি গোরুটিন হিসাবে অভিবাদন ফাংশন চালু করুন এবং সময়ের সাথে 100ms অপেক্ষা করুন। প্রধান প্রস্থান করার আগে ঘুমান।
ইঙ্গিত দেখান
একটি ফাংশন কলের সামনে `go` গুরুটিন চালু করে।
সমাধান 3 প্রচেষ্টার পরে উপলব্ধ
'হাই' প্রিন্ট করে এমন একটি গোরুটিন হিসাবে একটি বেনামী ফাংশন চালু করুন।
ইঙ্গিত দেখান
একটি বেনামী ফাংশনকে একটি ট্রেইলিং দিয়ে বলা হয় `()`: `go func(){...}()`।
সমাধান 3 প্রচেষ্টার পরে উপলব্ধ
একটি গোরুটিন সম্পূর্ণ হওয়ার আগে `প্রধান` প্রস্থান করলে কি হবে?
func main() {
go work()
// main ritorna immediatamente
}রিক্যাপ
go f()একই সাথে f() চালু করে; এটা অবিলম্বে ফিরে.- গোরুটিন = ~2 KB প্রাথমিক, কয়েকটি OS থ্রেডে মাল্টিপ্লেক্স করা হয়েছে।
mainঅপেক্ষা করে না: আপনার সিঙ্ক্রোনাইজেশন প্রয়োজন (চ্যানেল/ওয়েটগ্রুপ/প্রসঙ্গ)।time.Sleepশুধুমাত্র শিক্ষামূলক, কখনোই উৎপাদনে সিঙ্কের জন্য নয়।- Go 1.22 থেকে
forভেরিয়েবলটি প্রতিটি পুনরাবৃত্তিতে "তাজা" (আর "3 3 3" বাগ নেই)।