মূল কন্টেন্টে যান
মডিউল 7 · 1-এর পাঠ 5কোর্সে 31/50~12 min
মডিউল পাঠ (1/5)

Goroutines: লাইটওয়েট সমান্তরালতা

একটি গোরুটিন হল Go দ্বারা পরিচালিত সমসাময়িক সম্পাদনের একটি ইউনিট রানটাইম আপনি একটি ফাংশনের সামনে go কীওয়ার্ড দিয়ে একটি চালু করুন৷ কল:

Go
go greet("Anna")         // chiamata a funzione esistente
go func() {              // funzione anonima
    fmt.Println("hi")
}()

go বিবৃতিটি অবিলম্বে ফিরে আসে: গোরুটিন শুরু হয় সমান্তরাল এবং কলার চলতে থাকে।

কেন তারা "হালকা"

  • প্রাথমিক স্ট্যাক ~2KB (গতিশীলভাবে বৃদ্ধি পায়, প্রয়োজনে শত শত এমবি পর্যন্ত)।
  • রানটাইম (GOMAXPROCS) দ্বারা অল্প সংখ্যক OS থ্রেডে মাল্টিপ্লেক্সড।
  • হাজার হাজার/মিলিয়ন গোরুটিন রুটিন; OS থ্রেডের সাথে তারা অসম্ভব হবে।

ধারণাগতভাবে এটি "সমসাময়িক অগ্নি-এবং-ভুলে", কিন্তু সব সঙ্গে সমন্বয় করার জন্য বাহাদুরী সরঞ্জাম (চ্যানেল, sync.WaitGroup, context)।

প্রধান অপেক্ষা করে না

Go
func main() {
    go func() { fmt.Println("ciao dalla goroutine") }()
    // main esce subito: niente garanzia che la goroutine completi
}

যখন main ফিরে আসে, প্রক্রিয়াটি শেষ হয়ে যায়: গোরুটিন পাওয়া যায় না "তাদের কাজ শেষ করার জন্য", তাদের সাথে একসাথে হত্যা করা হয় প্রক্রিয়া স্পষ্ট সিঙ্ক্রোনাইজেশন প্রয়োজন.

সিঙ্ক্রোনাইজেশন: একটি পূর্বরূপ

তিনটি টুল যা আপনি পরবর্তী পাঠে দেখতে পাবেন:

Go
// 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 পর্যন্ত এটি একটি ঘন ঘন গোটচা ছিল:

Go
for i := 0; i < 3; i++ {
    go func() { fmt.Println(i) }()  // stampa "3 3 3" su versioni vecchie
}

Go 1.22 থেকে for ভেরিয়েবলটি নতুনভাবে প্রতিটিতে তৈরি করা হয়েছে পুনরাবৃত্তি, তাই বাগটি ডিফল্টরূপে সংশোধন করা হয়। পুরানো কোডবেসে আপনি হবে এখনও ফিক্স প্যাটার্ন দেখুন:

Go
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 KB1–8 MB (শুরুতে বরাদ্দ)
সৃষ্টিন্যানোসেকেন্ডমাইক্রোসেকেন্ড
সময়সূচীরানটাইম যান (সমবায়)কার্নেল (আগে)
ব্যবহারিক গণনা100K+কয়েক হাজার

একটি একক ওএস থ্রেড অনেকগুলি গোরুটিন হোস্ট করতে পারে। রানটাইম চলে যখন প্রয়োজন হয় থ্রেড জুড়ে goroutines.

চেষ্টা করে দেখুন

ব্যায়াম#go.m7.l1.e1
প্রচেষ্টা: 0লোড হচ্ছে...

একটি গোরুটিন হিসাবে অভিবাদন ফাংশন চালু করুন এবং সময়ের সাথে 100ms অপেক্ষা করুন। প্রধান প্রস্থান করার আগে ঘুমান।

সম্পাদক লোড হচ্ছে...
ইঙ্গিত দেখান

একটি ফাংশন কলের সামনে `go` গুরুটিন চালু করে।

সমাধান 3 প্রচেষ্টার পরে উপলব্ধ

ব্যায়াম#go.m7.l1.e2
প্রচেষ্টা: 0লোড হচ্ছে...

'হাই' প্রিন্ট করে এমন একটি গোরুটিন হিসাবে একটি বেনামী ফাংশন চালু করুন।

সম্পাদক লোড হচ্ছে...
ইঙ্গিত দেখান

একটি বেনামী ফাংশনকে একটি ট্রেইলিং দিয়ে বলা হয় `()`: `go func(){...}()`।

সমাধান 3 প্রচেষ্টার পরে উপলব্ধ

Quiz#go.m7.l1.e3
প্রস্তুত

একটি গোরুটিন সম্পূর্ণ হওয়ার আগে `প্রধান` প্রস্থান করলে কি হবে?

Go
func main() {
  go work()
  // main ritorna immediatamente
}
উত্তরের বিকল্প

রিক্যাপ

  • go f() একই সাথে f() চালু করে; এটা অবিলম্বে ফিরে.
  • গোরুটিন = ~2 KB প্রাথমিক, কয়েকটি OS থ্রেডে মাল্টিপ্লেক্স করা হয়েছে।
  • main অপেক্ষা করে না: আপনার সিঙ্ক্রোনাইজেশন প্রয়োজন (চ্যানেল/ওয়েটগ্রুপ/প্রসঙ্গ)।
  • time.Sleep শুধুমাত্র শিক্ষামূলক, কখনোই উৎপাদনে সিঙ্কের জন্য নয়।
  • Go 1.22 থেকে for ভেরিয়েবলটি প্রতিটি পুনরাবৃত্তিতে "তাজা" (আর "3 3 3" বাগ নেই)।